Django ListView¶
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¶
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">« 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 »</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.