Skip to content

Create Vaccine

Resources:

In this video, we are going to learn how to perform create operation for vaccine model using class based view.

Forms

First of all, create a form.py file in your vaccine app. Now, we have to import ModelForm from django.forms.

from django.forms import ModelForm

Then, we have to import the Vaccine Model

from vaccine.models import Vaccine

After that, lets create a VaccineForm that inherits ModelForm. Then create a Meta class.

class Meta:

Inside the meta class, we need to specify two thing. One is model and another is fields.

So, write model = Vaccine.

model = Vaccine

Now, this form is a ModelForm for Vaccine Model.

After that, we need to specify which model fields, we want in our forms. Since, I want to include all the model fields, so I can write.

fields = "__all__"

In this way, we have create a model form for Vaccine. This VaccineForm will include all the model fields of Vaccine model.

[Open center/forms.py and explain this]

In the previous section of video, we create a model form for center. In that model form, we added class named form-control to every field of that form. Now, I want similar behaviour in the vaccine form also. So, copy the constructor of CenterForm and paste it in the VaccineForm.

Then modify the form name in super.

def __init__(self, *args, **kwargs):
    super(VaccineForm, self).__init__(*args, **kwargs)
    for visible in self.visible_fields():
        visible.field.widget.attrs["class"] = "form-control"

Now, in our vaccineform, we have some form fields and every form fields will have class named "form-control". This a bootstrap css class name to make our form field, look much attractive, dynamic and resonsive.

[Complete Code: forms.py]

from django.forms import ModelForm
from vaccine.models import Vaccine

class VaccineForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(VaccineForm, self).__init__(*args, **kwargs)
        for visible in self.visible_fields():
            visible.field.widget.attrs["class"] = "form-control"

    class Meta:
        model = Vaccine
        fields = "__all__"

Views

Since, we have create the VaccineForm, we can now create the view to handle the create operation of vaccine.

In the views.py file, create a class based view named "CreateVaccine".

class CreateVaccine(View):

In this create vaccine view, we have to add some class attributes like form_class and template name.

So, write:

form_class = VaccineForm

Also, import this form from forms.py file.

from vaccine.forms import VaccineForm

After that, add a template name.

template_name = "vaccine/create-vaccine.html"

Now, we have to create this template in the vaccine folder inside the template file.

In the template file, we have to include the form component which we created in the last section of video.

{% include "components/form.html" with form_name="Create Vaccine" %}

In this way, we have create form_class and template name in the CreateVaccine View. Now, we don't need to write the form name and template name again and again in the get and post method of this view.

Now, first of all, lets handle the get method. Create a class method named get.

def get(self, request):

When the user sends the get method, we have to render form to the screen. So, create a context and add the form.

context = {
            "form": self.form_class,
        }

After that render the template.

return render(request, self.template_name, context)

In this way, we have create a get method that renders an HTML page along with the VaccineForm.

Now, lets handle the post request for this view. So, when the user fills the details and submit the form, we have to handle that post request and create a new vaccine instance.

Therefore, create a new class method named "post".

def post(self, request):

In this post method, first of all, we will instantiate the form with Post data.

form = self.form_class(request.POST)

Now, lets check whether the form is valid or not.

if form.is_valid():

If the form is valid, we have to save the form.

form.save()

And after saving the form, we need to redirect the user back to the list page.

from django.http import HttpResponseRedirect
from django.urls import reverse

return HttpResponseRedirect(reverse("vaccine:list"))

If the form is not valid, then we will render the same form along with the errors.

return render(request, self.template_name, {"form": form})

In this way, we have created a get and post method to handle the create operation for vaccine model.

URL

Now, lets create a url path for the CreateVaccine view.

path("create/", views.CreateVaccine.as_view(), name="create"),

After that, add this url path in the vaccine list page.

<a href="{% url 'vaccine:create' %}"><i class="fas fa-plus"></i> Create Vaccine</a>

[Run the development server and see the changes.]

class CreateVaccine(View):
    form_class = VaccineForm
    template_name = "vaccine/create-vaccine.html"

    def get(self, request):
        context = {
            "form": self.form_class,
        }
        return render(request, self.template_name, context)

    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse("vaccine:list"))
        return render(request, self.template_name, {"form": form})

Templates

Currently, our create center page looks very ugly. So, lets make it attractive and beautiful.

I have attached create-vaccine.html file in the resources section, download it, copy its content and paste it in the create-vaccine.html file.

{% extends 'mysite/base.html' %}

{% block title %} 
    <title>Create Vaccine</title>
{% endblock title %}

{% block content %}
<div class="card p-3">
  <div class="card-body">
    <h4 class="mb-3">Fill the following details to create a new vaccine</h4>
    {% include "components/form.html" with form_name="Create Vaccine" %}
  </div>
</div>
{% endblock content %}

Now, our create vaccine page looks much more better. In this way, we have learnt how to handle create operation for a given model using class based view.