Django DetailView

Django DetailView UML

Why django DetailView?

  • Django detailview is most commonly used to present a single model instance data.
  • It comes with in-built functionality like
  • model instace query
  • sending the required context to template
  • template rendering
  • As it inherits base classes BaseDetailView, SingleObjectTemplateResponseMixin, we can override the inherited methods as needed.

most used DetailView attributes

model:

  • The model that this view will display data for.
  • Specifying model = Foo is effectively the same as specifying queryset = Foo.objects.all()
  • Use it if queryset needs to have all objects.

queryset:

  • A QuerySet that represents the objects.
  • Use it if queryset needs some filtering which is not dynamic.
  • Example: queryset = Foo.objects.filter(is_active=True)
  • It's not recommended to use both model and queryset together

pk_url_kwarg

  • The name of the URLConf keyword argument that contains the primary key.
  • By default, pk_url_kwarg is 'pk'.
  • It will be used to lookup the object in the database.

slug_url_kwarg:

  • The name of the URLConf keyword argument that contains the slug.
  • By default, slug_url_kwarg is 'slug'.

query_pk_and_slug

  • If True, causes get_object() to perform its lookup using both the primary key and the slug.
  • Defaults to False.

template_name

  • The full name of a template to use as defined by a string.
  • example: template_name="comments/comment_detail.html"

Most used DetailView methods

get_object

  • Returns the single object that this view will display.
  • Can be overriden if object lookup requires additional attributes lookup along with pk

get_context_data

  • This method is responsible to pass the reqiured context to the template
  • By default it pass object, view to template
  • Can override this method to pass the extra context.

Example implementation of DetailView

Let's consider a e-commerce domain and we want to create a product detail page.

app/models.py

from django.db import models

class Product(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()

app/urls.py

from django.urls import path

urlpatterns = [
    path("product/<pk:int>/")
]

app/views.py

from django.views.generic.detail import DetailView
from app.models import Product

class ProductDetailView(DetailView):
    model = Product
    template_name = "product/detail.html"

templates/product/detail.html

Title: {{ object.title }}
Decsription: {{ object.description }}

If we want to send extra data to template then we can override the get_content_data method. Then, we can modify the detailview as below.

from django.views.generic.detail import DetailView
from app.models import Product

class ProductDetailView(DetailView):
    model = Product
    template_name = "product/detail.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        # send extra data here
        context["note"] = "Django is awesome"
        return context

Then, in the template we can do like

Title: {{ object.title }}
Description: {{ object.description }}

note: {{note}}

Similarly, we can override other methods like get_object, get_queryset, etc. as needed. we can check all available methods in django github repo.

References