diff options
Diffstat (limited to 'docs/intro/tutorial04.txt')
| -rw-r--r-- | docs/intro/tutorial04.txt | 140 |
1 files changed, 72 insertions, 68 deletions
diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt index dfbd82df55..9568546291 100644 --- a/docs/intro/tutorial04.txt +++ b/docs/intro/tutorial04.txt @@ -232,6 +232,7 @@ tutorial so far:: Change it like so:: from django.conf.urls.defaults import * + from django.views.generic import DetailView, ListView from polls.models import Poll info_dict = { @@ -239,88 +240,91 @@ Change it like so:: } urlpatterns = patterns('', - (r'^$', 'django.views.generic.list_detail.object_list', info_dict), - (r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict), - url(r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'), + (r'^$', + ListView.as_view( + models=Poll, + context_object_name='latest_poll_list' + template_name='polls/index.html')), + (r'^(?P<pk>\d+)/$', + DetailView.as_view( + models=Poll, + template_name='polls/detail.html')), + url(r'^(?P<pk>\d+)/results/$', + DetailView.as_view( + models=Poll, + template_name='polls/results.html'), + 'poll_results'), (r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote'), ) We're using two generic views here: -:func:`~django.views.generic.list_detail.object_list` and -:func:`~django.views.generic.list_detail.object_detail`. Respectively, those two -views abstract the concepts of "display a list of objects" and "display a detail -page for a particular type of object." +:class:`~django.views.generic.list.ListView` and +:class:`~django.views.generic.detail.DetailView`. Respectively, those +two views abstract the concepts of "display a list of objects" and +"display a detail page for a particular type of object." - * Each generic view needs to know what data it will be acting upon. This - data is provided in a dictionary. The ``queryset`` key in this dictionary - points to the list of objects to be manipulated by the generic view. + * Each generic view needs to know what model it will be acting + upon. This is provided using the ``model`` parameter. - * The :func:`~django.views.generic.list_detail.object_detail` generic view - expects the ID value captured from the URL to be called ``"object_id"``, - so we've changed ``poll_id`` to ``object_id`` for the generic views. + * The :class:`~django.views.generic.list.DetailView` generic view + expects the primary key value captured from the URL to be called + ``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic + views. - * We've added a name, ``poll_results``, to the results view so that we have - a way to refer to its URL later on (see the documentation about - :ref:`naming URL patterns <naming-url-patterns>` for information). We're - also using the :func:`~django.conf.urls.default.url` function from + * We've added a name, ``poll_results``, to the results view so + that we have a way to refer to its URL later on (see the + documentation about :ref:`naming URL patterns + <naming-url-patterns>` for information). We're also using the + :func:`~django.conf.urls.default.url` function from :mod:`django.conf.urls.defaults` here. It's a good habit to use - :func:`~django.conf.urls.defaults.url` when you are providing a pattern - name like this. + :func:`~django.conf.urls.defaults.url` when you are providing a + pattern name like this. -By default, the :func:`~django.views.generic.list_detail.object_detail` generic -view uses a template called ``<app name>/<model name>_detail.html``. In our -case, it'll use the template ``"polls/poll_detail.html"``. Thus, rename your -``polls/detail.html`` template to ``polls/poll_detail.html``, and change the -:func:`~django.shortcuts.render_to_response` line in ``vote()``. +By default, the :class:`~django.views.generic.list.DetailView` generic +view uses a template called ``<app name>/<model name>_detail.html``. +In our case, it'll use the template ``"polls/poll_detail.html"``. The +``template_name`` argument is used to tell Django to use a specific +template name instead of the autogenerated default template name. We +also specify the ``template_name`` for the ``results`` list view -- +this ensures that the results view and the detail view have a +different appearance when rendered, even though they're both a +:class:`~django.views.generic.list.DetailView` behind the scenes. -Similarly, the :func:`~django.views.generic.list_detail.object_list` generic -view uses a template called ``<app name>/<model name>_list.html``. Thus, rename -``polls/index.html`` to ``polls/poll_list.html``. +Similarly, the :class:`~django.views.generic.list.ListView` generic +view uses a default template called ``<app name>/<model +name>_list.html``; we use ``template_name`` to tell +:class:`~django.views.generic.list.ListView` to use our existing +``"polls/index.html"`` template. -Because we have more than one entry in the URLconf that uses -:func:`~django.views.generic.list_detail.object_detail` for the polls app, we -manually specify a template name for the results view: -``template_name='polls/results.html'``. Otherwise, both views would use the same -template. Note that we use ``dict()`` to return an altered dictionary in place. +In previous parts of the tutorial, the templates have been provided +with a context that contains the ``poll`` and ``latest_poll_list`` +context variables. For DetailView the ``poll`` variable is provided +automatically -- since we're using a Django model (``Poll``), Django +is able to determine an appropriate name for the context variable. +However, for ListView, the automatically generated context variable is +``poll_list``. To override this we provide the ``context_object_name`` +option, specifying that we want to use ``latest_poll_list`` instead. +As an alternative approach, you could change your templates to match +the new default context variables -- but it's a lot easier to just +tell Django to use the variable you want. -.. note:: :meth:`django.db.models.QuerySet.all` is lazy +You can now delete the ``index()``, ``detail()`` and ``results()`` +views from ``polls/views.py``. We don't need them anymore -- they have +been replaced by generic views. - It might look a little frightening to see ``Poll.objects.all()`` being used - in a detail view which only needs one ``Poll`` object, but don't worry; - ``Poll.objects.all()`` is actually a special object called a - :class:`~django.db.models.QuerySet`, which is "lazy" and doesn't hit your - database until it absolutely has to. By the time the database query happens, - the :func:`~django.views.generic.list_detail.object_detail` generic view - will have narrowed its scope down to a single object, so the eventual query - will only select one row from the database. +The ``vote()`` view is still required. However, it must be modified to +match the new context variables. In the +:func:`~django.shortcuts.render_to_response` call, rename the ``poll`` +context variable to ``object``. - If you'd like to know more about how that works, The Django database API - documentation :ref:`explains the lazy nature of QuerySet objects - <querysets-are-lazy>`. - -In previous parts of the tutorial, the templates have been provided with a -context that contains the ``poll`` and ``latest_poll_list`` context variables. -However, the generic views provide the variables ``object`` and ``object_list`` -as context. Therefore, you need to change your templates to match the new -context variables. Go through your templates, and modify any reference to -``latest_poll_list`` to ``object_list``, and change any reference to ``poll`` -to ``object``. - -You can now delete the ``index()``, ``detail()`` and ``results()`` views -from ``polls/views.py``. We don't need them anymore -- they have been replaced -by generic views. - -The ``vote()`` view is still required. However, it must be modified to match the -new context variables. In the :func:`~django.shortcuts.render_to_response` call, -rename the ``poll`` context variable to ``object``. - -The last thing to do is fix the URL handling to account for the use of generic -views. In the vote view above, we used the -:func:`~django.core.urlresolvers.reverse` function to avoid hard-coding our -URLs. Now that we've switched to a generic view, we'll need to change the -:func:`~django.core.urlresolvers.reverse` call to point back to our new generic -view. We can't simply use the view function anymore -- generic views can be (and -are) used multiple times -- but we can use the name we've given:: +The last thing to do is fix the URL handling to account for the use of +generic views. In the vote view above, we used the +:func:`~django.core.urlresolvers.reverse` function to avoid +hard-coding our URLs. Now that we've switched to a generic view, we'll +need to change the :func:`~django.core.urlresolvers.reverse` call to +point back to our new generic view. We can't simply use the view +function anymore -- generic views can be (and are) used multiple times +-- but we can use the name we've given:: return HttpResponseRedirect(reverse('poll_results', args=(p.id,))) |
