summaryrefslogtreecommitdiff
path: root/docs/intro/tutorial04.txt
diff options
context:
space:
mode:
Diffstat (limited to 'docs/intro/tutorial04.txt')
-rw-r--r--docs/intro/tutorial04.txt140
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,)))