How to create a checkout form in an E-commerce Shop with Django? Part 4.
In the previous Part 3 we create models for Order and in this Part 4 of Create an E-commerce Shop with Django we will create checkout form an order.
Prerequisites
- Django Latest Version
- Virtual Environment
- IDE PyCharm or Visual Studio Code
1. Form
In this part of the tutorial we will create a checkout form.
Checkout.html file has been adjusted to the needs of the checkout display. then we only need to create a form from the core directory.
Then in the core directory create a new file called forms.py where this file will store everything related to the form.
Import :
from django import forms
from django_countries.fields import CountryField
from django_countries.widgets import CountrySelectWidget
You can see we are using the country field library and this is a third party library so we have to install it to use it. to install country library jus run command below :
$ pip install django-countries
and in project’s settings.py add this code :
INSTALLED_APPS = [
...
'django_countries',
]
Then we create a class form called CheckoutForm as a form from the checkout page.
PAYMENT = (
('S', 'Stripe'),
('P', 'Paypal')
)
class CheckoutForm(forms.Form):
street_address = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': '1234 Main St.'
}))
apartment_address = forms.CharField(required=False, widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Apartment or suite'
}))
country = CountryField(blank_label='(select country)').formfield(widget=CountrySelectWidget(attrs={
'class': 'custom-select d-block w-100'
}))
zip = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control'
}))
same_billing_address = forms.BooleanField(required=False)
save_info = forms.BooleanField(required=False)
payment_option = forms.ChoiceField(
widget=forms.RadioSelect, choices=PAYMENT
)
And with this you will have checkout form.
2. Models
To create a checkout form we will create a new model class that functions to save shipping address an order.
the class we will create is CheckoutAddress which will store the shipping address of the order from the form we made before.
class CheckoutAddress(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
street_address = models.CharField(max_length=100)
apartment_address = models.CharField(max_length=100)
country = CountryField(multiple=False)
zip = models.CharField(max_length=100)
def __str__(self):
return self.user.username
dont forget as well to impor becouse we would use Country Field:
from django_countries.fields import CountryField
Do not forget migrate your model database with the command below :
$ python manage.py migrate
$ python manage.py makemigrations
3. Views
In the view don’t forget to add the country field library and don’t forget to add the model and form that we just created
from .forms import CheckoutForm
from .models import (
...
CheckoutAddress
)
Create CheckoutView class
class CheckoutView(View):
def get(self, *args, **kwargs):
form = CheckoutForm()
context = {
'form': form
}
return render(self.request, 'core/checkout.html', context=context)
def post(self, *args, **kwargs):
form = CheckoutForm(self.request.POST or None)
try:
order = Order.objects.get(user=self.request.user, ordered=False)
if form.is_valid():
street_address = form.cleaned_data.get('street_address')
apartment_address = form.cleaned_data.get('apartment_address')
country = form.cleaned_data.get('country')
zip = form.cleaned_data.get('zip')
same_billing_address = form.cleaned_data.get('same_billing_address')
save_info = form.cleaned_data.get('save_info')
payment_option = form.cleaned_data.get('payment_option')
checkout_address = CheckoutAddress(
user=self.request.user,
street_address=street_address,
apartment_address=apartment_address,
country=country,
zip=zip
)
checkout_address.save()
order.checkout_address = checkout_address
order.save()
return redirect('core:checkout')
messages.warning(self.request, 'Fail checkout')
return redirect('core:checkout')
except ObjectDoesNotExist:
messages.error(self.request, 'You do not have an order')
return redirect('core:order-summary')
In the forms.py file that we made earlier. we send the form into templates via view. The post function that captures the value sent via the form in the templates.
4. Urls
As usual after we make the view don’t forget to register it in the core/urls.py file.
Import
from django.urls import path
from .views import (
...
CheckoutView
)
Register all your class and fuctions in views to urls.py file. after that we will add the address in
Create path url to checkout page with code below:
urlpatterns = [
...
path('checkout', CheckoutView.as_view(), name='checkout'),
]
And finally the checkout form can be accessed and save the order data into the database
Proceed to the next part!
I hope you’ve found the fourth part of this tutorial helpful. In the next session, we’re going to handling payment with stripe to this E-Commerce Website.
You can visit github where find other scripts.