Skip to content

Slot Create

In this video, we are going to make slot create page. Using this page, the admin can create the slot for a particular campaign.

Resources

Forms

In the forms.py file, at first import the slot model

from campaign.models import Slot

Now, create the SlotForm.

class SlotForm(ModelForm):
    # Now, create the meta class and specify the model and fields which you want in this form
    class Meta:
        model = Slot
        fields = "__all__"

Views

Now, in the views.py file, lets create the SlotCreateView.

# This view will inherit LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, generic.CreateView
class SlotCreateView(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, generic.CreateView):
    # In this view, at first, specify the model name
    model = Slot
    # Now, specify the form [Also import it]
    form_class = SlotForm
    # Then, give the name of the template
    template_name = "campaign/slot-create.html"
    # After that, set the permission required to access this view.
    permission_required = ("campaign.add_slot",)
    # At last, provide the success message
    success_message = "Slot Created Successfully"

    # Now, we also need to provide the success url which the user will be redirected once they complete the create operation.
    def get_success_url(self):
        return reverse_lazy("campaign:slot-list", kwargs={"campaign_id": self.kwargs["campaign_id"]})

Templates

Now, create the slot-create.html file in the templates folder under campaign.

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

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

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

URLS

Now, create a url path to access this view.

path("<int:campaign_id>/slot/create/", views.SlotCreateView.as_view(), name="slot-create"),

After that, lets add this url path in the slot-list.html

<a href="{% url 'campaign:slot-create' campaign_id %}"><i class="fas fa-plus"></i> Create Slot</a>

In this url inside a tag, we are specifying campaign_id. But we haven't provided this value from our SlotListView. So, open the SlotListView and add context data.

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["campaign_id"] = self.kwargs["campaign_id"]
        return context

[Run the development server and see the changes.]

Forms

If you properly see the slot create form, then you can observe that, in the campaign field, we are getting a list of campaigns to select but we already know the campaign for which are creating this slot. So, we need to remove the other choices except the one which are we creating the slot for.

At first, we will select the default campaign id. For that we need to override the get_initial method.

    def get_initial(self):
        initial = super().get_initial()
        initial["campaign"] = Campaign.objects.get(id=self.kwargs["campaign_id"])
        return initial

Now, lets override the form constructor to remove other choices of campaign.

    def __init__(self, campaign_id, *args, **kwargs):
        super(SlotForm, self).__init__(*args, **kwargs)
        self.fields["campaign"].queryset = Campaign.objects.filter(id=campaign_id)
        # We will also disable this field so that user cannot change its value
        self.fields["campaign"].disabled = True
        # After that, we will disble this reserved value. Because this value represents the number of patients who have made a reservation on this slot and we don't want any user to manipulate this value.
        self.fields["reserved"].disabled = True
        # Now add the form-control to every fields of this form.
        for visible in self.visible_fields():
            visible.field.widget.attrs["class"] = "form-control"

This form constructor takes campaign_id so, we need to provide the campaig id from our django view.

    # To provide any extra context data to the form during form initialization, we need to override the get_form_kwargs method.
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs["campaign_id"] = self.kwargs["campaign_id"]
        return kwargs

[Run the development server and see the changes.]