Django ListView

Django ListView UML

When to use django ListView?

  • It's generic django view designed for presenting the list of objects in a HTML page.
  • It't allows us to re-use the built-in functionality provided by the list view.
  • We can use the methods from the ListView to overload or override the default functionality to achieve the required functionality.

Request flow in django ListView

Django ListView

Let's implement django ListView

use case: Let's consider the scenario of listing products and their information in a product listing page.

models.py

from django.db import models

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

    class Meta:
        db_model = 'product'

views.py

from django.views.generic.list import ListView
from .models import Product

class ProductListView(ListView):
    model = Product
    template_name = 'product_list.html'

urls.py

from django.urls import path

from .views import ProductListView

urlpatterns = [
    path('products/', ProductListView.as_view(), name='product-list'),
]

templates/product_list.html

{% for product in object_list %}
Title: {{product.title}}<br/>
Description: {{product.description}}<br/>
{% endfor %}

Let's access the url http://localhost:8000/products to see the products.

It's that simple to implement the listing of products in the list page. But, if we have more products, let's say 10,000 products are in the table then it's not a good solution to use the above code.

Let's implement the pagination

Now, we need to use the the pagination in the list view. Let's implement the pagination.

views.py

from django.views.generic.list import ListView
from .models import Product

class ProductListView(ListView):
    model = Product
    template_name = 'product_list.html'
    paginate_by = 10
  • Let's modify the template to show the pagination to the user.

product_list.html

{% for obj in object_list %}
    <li>Title: {{obj.title}}</li>
    <li>Description: {{obj.description}}</li>
{% endfor %}

{% if page_obj.has_previous %}
    <a href="?page=1">&laquo; first</a>
    <a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}

Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.

{% if page_obj.has_next %}
    <a href="?page={{ page_obj.next_page_number }}">next</a>
    <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
{% endif %}

By default, django list view pass the context object_list, page_obj to the template.

  • object_list - is a iterable object of model instances.
  • page_obj - is a paginated object contains pagination info if paginated.

Additional info

  • Can override the methods like get_context_data, get, dispatch as required.
  • Can use mixins and other helper function as needed to achieve the required feature.

Reference: