“Implementeer eenvoudig dataviews met Django ListView en DetailView,
verhoog uw ontwikkelingsproductiviteit!”

In het vorige artikel hebben we de basis View-klasse en FormView van Django besproken. Nu is het tijd om verder te gaan naar de meer specifieke generieke weergaven (Generic Views).
ListView en DetailView zijn vooral gespecialiseerd in ‘data-uitvoer’ en helpen je om met slechts een paar instellingen snel een lijstpagina en detailpagina te implementeren.


1. Wat zijn ListView en DetailView?

  1. ListView

    • Het biedt de mogelijkheid om meerdere objecten van een model (Model) in lijstvorm weer te geven.

    • Met eenvoudige implementatie van paginering (Pagination), sorteren en zoekfunctionaliteiten kan het op de meeste “lijstpagina’s” worden toegepast.

  2. DetailView

    • Toont de details van een specifiek object (bijvoorbeeld artikelen, producten, gebruikers, enz.).

    • Je kunt het overeenkomstige object vinden via URL-parameters of de pk (primary key) waarde en eenvoudig weergeven in de sjabloon.

Deze twee klassen zijn een deel van de generieke weergaven die Django biedt en zijn krachtige tools die snel de “Lezen” rol van CRUD implementeren.


2. Basisstructuur en gebruik van ListView

ListView verwerkingsdiagram

2.1 Basisvoorbeeld

# views.py
from django.views.generic import ListView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'post_list.html'
    context_object_name = 'posts'  # Contextvariabele voor de sjabloon (standaard: object_list)
    # paginate_by = 10  # Aantal te tonen items per pagina (optioneel)

    # (Optie) Gebruik get_queryset voor extra aanpassing van de queryset
    def get_queryset(self):
        # Bijvoorbeeld: alleen de nieuwste artikelen tonen?
        return Post.objects.order_by('-created_at')
  • model: Geeft aan welk modeldata moet worden weergegeven.

  • template_name: Pad naar het sjabloonbestand (standaard: <app_name>/<model_name>_list.html).

  • context_object_name: Naam van het contextobject dat in de sjabloon wordt gebruikt (standaard: object_list).

  • paginate_by: Geeft het aantal objecten aan dat per pagina moet worden weergegeven (paginering).

2.2 ListView koppelen in urls.py

# urls.py
from django.urls import path
from .views import PostListView

urlpatterns = [
    path('posts/', PostListView.as_view(), name='post_list'),
]

2.3 Basis sjabloonvoorbeeld

<!-- post_list.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Artikeloverzicht</title>
</head>
<body>
    <h1>Artikeloverzicht</h1>
    <ul>
        {% for post in posts %}
            <li>
                <a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a>
            </li>
        {% endfor %}
    </ul>

    <!-- Bij paginering -->
    {% if is_paginated %}
      <div>
        {% if page_obj.has_previous %}
          <a href="?page={{ page_obj.previous_page_number }}">Vorige</a>
        {% endif %}
        <span>Pagina {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}</span>
        {% if page_obj.has_next %}
          <a href="?page={{ page_obj.next_page_number }}">Volgende</a>
        {% endif %}
      </div>
    {% endif %}
</body>
</html>

Belangrijkste zoekwoorden: “Automatisering van lijstpagina's”, “Paginering”, “Efficiënte dataweergave”


3. Basisstructuur en gebruik van DetailView

3.1 Basisvoorbeeld

# views.py
from django.views.generic import DetailView
from .models import Post

class PostDetailView(DetailView):
    model = Post
    template_name = 'post_detail.html'
    context_object_name = 'post'  # Contextvariabele voor de sjabloon (standaard: object)

    # (Optie) Als je een andere identificator dan pk uit de URL wilt gebruiken, kan dit worden overschreven met get_slug_field.
  • model: Zoekt een enkele object van een specifiek model.

  • template_name: Pad naar het sjabloonbestand (standaard: <app_name>/<model_name>_detail.html).

  • context_object_name: Naam van het contextobject dat in de sjabloon wordt gebruikt (standaard: object).

  • Django zoekt automatisch objecten aan de hand van waarden die overeenkomen met patronen in de URL zoals <int:pk>/ of <slug:slug>/.

3.2 DetailView koppelen in urls.py

# urls.py
from django.urls import path
from .views import PostDetailView

urlpatterns = [
    path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'),
]

3.3 Basis sjabloonvoorbeeld

<!-- post_detail.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ post.title }}</title>
</head>
<body>
    <h1>{{ post.title }}</h1>
    <p>Gemaakt op: {{ post.created_at }}</p>
    <div>
        {{ post.content }}
    </div>
    <a href="{% url 'post_list' %}">Terug naar overzicht</a>
</body>
</html>

4. ListView & DetailView uitbreiden

4.1 get_queryset, get_context_data

get_queryset(): Je kunt de queryset aanpassen aan de gewenste voorwaarden.
Bijvoorbeeld: een lijst van artikelen die alleen door specifieke gebruikers kunnen worden bekeken, filteren op zoektermen, sorteren op bepaalde velden, enz.

def get_queryset(self):
    queryset = super().get_queryset()
    return queryset.filter(is_active=True)

get_context_data(): Je kunt extra gegevens doorgeven aan de sjabloon.

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['extra_info'] = 'Extra informatie'
    return context

4.2 slug, aangepaste lookup

DetailView kan in plaats van pk ook slug (een korte tekstidentificator) gebruiken, en je kunt slug_field, slug_url_kwarg, enz. specificeren voor aangepaste configuraties.

class PostDetailView(DetailView):
    model = Post
    slug_field = 'slug'           # de naam van het slugveld in het model
    slug_url_kwarg = 'slug'       # naam van de parameter die in het URL-patroon wordt ontvangen

4.3 Combineren met Mixin

  • Door samen te werken met LoginRequiredMixin of PermissionRequiredMixin, kun je eenvoudig de toegang tot de lijst- en detailpagina's beheren.

  • Het is ook mogelijk om aangepaste Mixins zoals SearchMixin te maken, waarmee je logica voor het verwerken van zoektermparameters in verschillende ListView's kunt hergebruiken.


5. Eenvoudig praktijkvoorbeeld: Realisatie van een forumfunctionaliteit

Post dat in het vorige artikel werd behandeld, gaan we een lijst + detail implementatie maken.
# models.py
class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(unique=True)  # voorbeeld van slug gebruik

    def __str__(self):
        return self.title
# views.py
from django.views.generic import ListView, DetailView
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'post_list.html'
    context_object_name = 'posts'
    paginate_by = 5  # 5 items per pagina

    def get_queryset(self):
        # We veronderstellen dat alleen actieve berichten worden getoond, niet op basis van slug
        return Post.objects.filter(is_active=True).order_by('-created_at')

class PostDetailView(DetailView):
    model = Post
    template_name = 'post_detail.html'
    context_object_name = 'post'
    slug_field = 'slug'
    slug_url_kwarg = 'slug'
# urls.py
urlpatterns = [
    path('posts/', PostListView.as_view(), name='post_list'),
    path('posts/<slug:slug>/', PostDetailView.as_view(), name='post_detail'),
]
  • Lijstpagina: Je kunt de lijst bekijken door het paginanummer te wijzigen, bijvoorbeeld /posts/?page=2.

  • Detailpagina: Zoek specifieke artikelen met het pad posts/<slug>/ en laat deze in de sjabloon zien.


6. Vergelijking met FBV: Hoe eenvoudig kan lijst/detailfunctionaliteit worden geïmplementeerd?

Categorie FBV (functie-gebaseerde weergave) ListView/DetailView (CBV)
Code structuur Schrijf aparte functies voor lijst/detail en implementeer paginering/sorteren zelf Gemakkelijke aanpassing met alleen instelllingen voor lijst, paginering, sorteren, zoeken enz.
Leesbaarheid/onderhoudbaarheid Voorwaarden en herhalingen wemelen door elkaar, waardoor complexiteit toeneemt naarmate het project groeit Lijst- en detaillogica zijn gescheiden; het is gemakkelijk om methoden te overschrijven voor uitbreiding, waardoor onderhoud eenvoudiger wordt.
Ontwikkelingsproductiviteit (Belangrijkste zoekwoord) “Toename code duplicatie, tijdverspilling” “Tijd besparen bij ontwikkeling, productiviteit verhogen”
Gegevensoverdracht naar sjablonen Handmatig een contextdictionary samenstellen en doorgeven aan render Standaard wordt context (object_list, object) automatisch doorgegeven. Extra gegevens kunnen eenvoudig worden verwerkt met get_context_data.
Geavanceerde functies zoals paginering en zoeken Vereist aparte logica Kan eenvoudig worden geactiveerd met ingebouwde functies en eigenschappen.

FBV vs DetailView - Eenvoudige objectquery


7. Conclusie en volgende post aankondigen

Django ListView en DetailView vereenvoudigen aanzienlijk de implementatie van “data-lijsten” en “detailpagina's”.
Door functies zoals paginering, het toevoegen van contextdata en het ophalen van objecten op basis van URL-parameters te automatiseren, krijg je aanzienlijke voordelen op het gebied van codehergebruik en ontwikkelingsproductiviteit.

De CBV (Class-Based View) serie gaat verder!
In de volgende post bekijken we hoe we eenvoudig CreateView, UpdateView en DeleteView kunnen gebruiken om CRUD-logica te implementeren.


Bekijk eerdere artikelen opnieuw

  1. Klasse-gebaseerde weergave (CBV) verkenningsserie #1 – Waarom van FBV naar CBV en de houding van de ontwikkelaar

  2. Klasse-gebaseerde weergave (CBV) verkenningsserie #2 – Basisstructuur van de View-klasse in Django begrijpen

  3. Klasse-gebaseerde weergave (CBV) verkenningsserie #3 – FormView voor eenvoudige formulierverwerking


“Profiteer van Django's ListView en DetailView voor
snelle dataverzoeken, eenvoudig ontwikkelingsbeheer en uitstekende productiviteit!”