Django generic base view¶
Django supports two types of views
- Function based views
- Class based views
Function based views are recommended to use when we have less complexity in functionality. But, when we have complex functionality to be implemented then we need to use class based views. Because, class based views are nothing but python classes. It supports OOP's concepts like inheritance and method overloading and method overriding. We can split the complex functionality into classes and methods and combine them using OOP's concepts.
Django provided with generic views for different use cases. The base class for all these generic views is View and all other generic classes inherits it's attributes and methods and extends the required functionalities.
Base View¶
- Find the UML diagram for the base view class view
http_method_names
attribute used to restrict the http method requests if not requiredas_view
method is the main entry point for a request-response process.http_method_not_allowed
method used to raise request method not allowed error.-
dispatch
method is called afteras_view
is called. It checks the request methodGET
,POST
, etc. and sends routes the request to that specific method if it's implemented otherwise it will callhttp_method_not_allowed
method to raise error method not allowed. -
Find the request flow in the below diagram
Example implementation of base View¶
- Let's see an example use case which will render a contact form for
GET
request method and sends an email to user when user submits the form.
template.html
<form action="" method="POST">
{% csrf_token %}
{{form.as_view()}}
<input type="submit" />
</form>
forms.py
from django import forms
class ContactForm(forms.Form):
from_email = forms.EmailField(required=True)
subject = forms.CharField(required=True)
message = forms.CharField(widget=forms.Textarea, required=True)
views.py
from django.views.generic import View
from django.core.mail import send_mail
from django.http import HttpResponse
from django.shortcuts import render
from .forms import ContactForm
class ContactView(View):
def get(self, request):
template_name = "template.html"
context = {
"form": ContactForm()
}
return render(request, template_name, context)
def post(self, request):
form = ContactForm(request.POST)
if form.is_valid():
from_email = form.cleaned_data.get("from_email")
subject = form.cleaned_data.get("subject")
message = form.cleaned_data.get("message")
to_email = "[email protected]"
send_mail(subject, message, from_email, [to_email])
return HttpResponse("")
else:
template_name = "template.html"
context = {"form": form}
return render(request, template_name, context)
urls.py
from . import views
urlpatterns = [
url('contact/', ContactView.as_view(), name="contact"),
]
If you see the above we have seperated the functionality for get
and post
requests so that the methods get
and post
are responsible to handle the request based on request method. If we write same code with function based views we will need to implement multiple if and else conditions and it doesn't allow the easy navigation of the code to change something.
The same can be implemented with FormView
with a few lines of code as the view contains above implemented functionality in-built.
Note: It's always recommended to use the class based views if we have complex functionality.