Django Class based views List and Details views


Template views are fine for static page and you could use them for everything with get_context_data but it would be barely better than using function as views.

Enter ListView and DetailView


from django.db import models

class Pokemon(models.Model):
    name = models.CharField(max_length=24)
    species = models.CharField(max_length=48)
    slug = models.CharField(max_length=48)


from django.views.generic import ListView, DetailView
from .models import Pokemon

class PokedexView(ListView):
    """ Provide a list of Pokemon objects """
    model = Pokemon
    paginate_by = 25

class PokemonView(DetailView):
    model = Pokemon

That's all you need to generate a view listing all your objects of a models and views of singular item. The list is even paginated. You can provide template_name if you want something specific. By default, it's generated from the model name.


<!DOCTYPE html>
<ul>{% for pokemon in pokemon_list %}
    <li><a href="{% url "app:pokemon" %}">{{ }}</a>
        &ndash; {{ pokemon.species }}

The context is populated with the list of object under two name, object_list and a second one build from the model name, here pokemon_list. If you have paginated the list, you have to take care of next and previous link too. The Paginator object can help with that, it's available in the context data too.


<!DOCTYPE html>
<title>Pokemon {{ }}</title>
<h1>{{ }}</h1>
<h2>{{ pokemon.species }} </h2>

As before, the context is populated with your model object under the name object and pokemon, the second one being derived from the model name.


from django.conf.urls import url
from . import views

app_name = 'app'
urlpatterns = [
    url(r'^pokemon/$', views.PokedexView.as_view(), name='pokedex'),
    url(r'^pokemon/(?P<pk>\d+)/$', views.PokemonView.as_view(), name='pokemon'),

In this snippet, the url for the detail view is built using the primary key. It's also possible to use a slug as argument. This gives a nicer looking url that's easier to remember. However it requires the presence of a field named slug in your model.

url(r'^pokemon/(?P<slug>[A-Za-z0-9_-]+)/$', views.PokemonView.as_view(), name='pokemon'),

If a field called slug is not present, you can use the slug_field setting in DetailView to point to a different field.

For pagination, use a page get parameters or put a page directly in the url.