Understanding Django Class based views
-
Back-End
Class based views are "ready to apply" made views for frequent development situation which don't require the amount of setting necessary to design a functional / classic view.
Below, there are paralled ilustrations of functional views versus class based views.
View
urls
path('my_view/', views.my_view, name='my_view'),views
#
#
def my_view(request):
if request.method == 'GET':
# <view logic>
return HttpResponse('result')template
...
urls
path('my_view_generic/', views.MyView.as_view(), name='my_view_generic'),views
from django.views import View
class MyView(View):
def get(self, request):
# <view logic>
return HttpResponse('result')template
...
Create
urls
path('create_view/',views.create_view, name="create_view"),views
def create_view(request):
# add the dictionary during initialization
form = GeeksForm(request.POST or None)
if form.is_valid():
form.save()
context ={}
#reset form fields
context['form'] = GeeksForm()
return render(request, "geeks/create_view.html", context)template
<form method="POST" enctype="multipart/form-data">
<!-- Security token -->
{% csrf_token %}
<!-- Using the formset -->
{{ form.as_p }}
<input type="submit" value="Submit">
</form>urls
path('create_view_generic/', views.GeeksCreate.as_view(), name="create_view_generic" ),views
from django.views.generic.edit import CreateView
#default template: geeks/templates/geeks/geeksmodel_form.html
class GeeksCreate(CreateView):
# specify the model for create view
model = GeeksModel
# specify the fields to be displayed
fields = ['title', 'description']
success_url="/geeks/create_view_generic/"template
<form method="POST" enctype="multipart/form-data">
<!-- Security token -->
{% csrf_token %}
<!-- Using the formset -->
{{ form.as_p }}
<input type="submit" value="Submit">
</form>Retrieve data:
1) List
urls
path('list_view/',views.list_view, name="list_view"),views
#
#
def list_view(request):
context ={}
# add the dictionary during initialization
context["dataset"] = GeeksModel.objects.all()
return render(request, "geeks/list_view.html", context)template
{% for data in dataset %}
{{ data.title }}<br/>
{{ data.description }}<br/>
<hr/>
<!-- If dataset is empty -->
{% empty %}
<li>No objects yet.</li>
{% endfor %}urls
path('list_view_generic/', views.GeeksList.as_view(), name="list_view_generic"),views
from django.views.generic.list import ListView
#default template : geeks/templates/geeks/geeksmodel_list.html
class GeeksList(ListView):
#modify default context_object_name
#context_object_name = 'all_geeks_list'
# specify the model for list view
model = GeeksModeltemplate
{% for object in object_list %}
{{ object.title }}<br/>
{{ object.description }}<br/>
<hr/>
<!-- If objet_list is empty -->
{% empty %}
No objects yet.
{% endfor %}2) Detail
urls
path('detail/<int:id>/', views.detail_view, name="detail" ),views
def detail_view(request, id):
context ={}
context["data"] = GeeksModel.objects.get(id = id)
return render(request, "geeks/detail_view.html", context)template
{{ data.title }}<br/>
{{ data.description }}<br/>urls
path('detail_generic/<int:pk>/', views.GeeksDetailView.as_view(), name="detail_generic"),views
#
from django.views.generic.detail import DetailView
#default template: geeks/templates/geeks/geeksmodel_detail.html
class GeeksDetailView(DetailView):
# specify the model to use
model = GeeksModeltemplate
<h1>{{ object.title }}</h1>
<p>{{ object.description }}</p>Update
urls
path('update/<int:id>/', views.update_view, name="update"),views
def update_view(request, id):
context ={}
# fetch the object related to passed id
obj = get_object_or_404(GeeksModel, id = id)
# pass the object as instance in form
form = GeeksForm(request.POST or None, instance = obj)
# save the data from the form and
# redirect to detail_view
if form.is_valid():
form.save()
return HttpResponseRedirect("/geeks/detail/"+str(id))
# add form dictionary to context
context["form"] = form
return render(request, "geeks/update_view.html", context)template
<form method="POST">
<!-- Security token by Django -->
{% csrf_token %}
<!-- form as paragraph -->
{{ form.as_p }}
<input type="submit" value="Update">
</form>urls
path('update_generic/<int:pk>/', views.GeeksUpdateView.as_view(), name="update_generic"),views
#
#
#
#
from django.views.generic.edit import UpdateView
#default template_name : geeks/templates/geeks/geeksmodel_form.html
class GeeksUpdateView(UpdateView):
# specify the model you want to use
model = GeeksModel
# specify the fields
fields = [
"title",
"description"
]
def get_success_url(self):
return f"/geeks/detail/{self.object.pk}"template
<form method="POST" >
<!-- Security token -->
{% csrf_token %}
<!-- Using the formset -->
{{ form.as_p }}
<input type="submit" value="Submit">
</form>Delete
urls
path('delete/<int:id>/', views.delete_view, name="delete" ),views
def delete_view(request, id):
context ={}
# fetch the object related to passed id
obj = get_object_or_404(GeeksModel, id = id)
if request.method =="POST":
# delete object
obj.delete()
# after deleting redirect to
# home page
return HttpResponseRedirect("/geeks/list_view/")
return render(request, "geeks/delete_view.html", context)template
<form method="POST">
<!-- Security token by Django -->
{% csrf_token %}
Are you sure you want to delete this item ?
<input type="submit" value="Yes" />
<a href="/geeks/">Cancel </a>
</form>urls
path('delete_generic/<int:pk>/', views.GeeksDeleteView.as_view(), name="delete_generic"),views
#
#
#
from django.views.generic.edit import DeleteView
#default template_name : geeks/templates/geeks/geeksmodel_confirm_delete.html
class GeeksDeleteView(DeleteView):
# specify the model you want to use
model = GeeksModel
# can specify success url
# url to redirect after successfully
# deleting object
success_url ="/geeks/list/"template
<form method="post">
<!-- Security token by Django -->
{% csrf_token %}
<p>Are you sure you want to delete "{{ object }}"?</p>
<input type="submit" value="Confirm">
<a href="/geeks/">Cancel </a>
</form>Some methods for customizing class based views:
- get_context_data() for defining additional context data for template
- queryset
- get_query_set() for customizing query
class GeeksCreate(CreateView):
# specify the model for create view
model = GeeksModel
# specify the fields to be displayed
fields = ['title', 'description']
success_url="/geeks/create_view_generic/"
#aditional context data, if needed
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['success'] = "True"
return context
class GeeksList2(ListView):
context_object_name = 'selected_geeks_list'
queryset = GeeksModel.objects.filter(title__startswith='book')
template_name = 'geeks/geeks_by_title.html'
class GeeksList3(ListView):
template_name = 'geeks/geeks_by_description.html'
def get_queryset(self):
return Book.objects.filter(description__contains="motorcycle")
Examples are inspired by a geeksforgeeks article and are available at django_tutorial git repo.