Browse Source

Fixed #20876 -- Changed Poll model name in tutorial to Question

Rodolfo 11 years ago
parent
commit
d34b94b00f

BIN
docs/intro/_images/admin02t.png


BIN
docs/intro/_images/admin03.png


BIN
docs/intro/_images/admin03t.png


BIN
docs/intro/_images/admin04.png


BIN
docs/intro/_images/admin04t.png


BIN
docs/intro/_images/admin05.png


BIN
docs/intro/_images/admin05t.png


BIN
docs/intro/_images/admin06.png


BIN
docs/intro/_images/admin06t.png


BIN
docs/intro/_images/admin07.png


BIN
docs/intro/_images/admin08.png


BIN
docs/intro/_images/admin08t.png


BIN
docs/intro/_images/admin09.png


BIN
docs/intro/_images/admin10.png


BIN
docs/intro/_images/admin11.png


BIN
docs/intro/_images/admin11t.png


BIN
docs/intro/_images/admin12.png


BIN
docs/intro/_images/admin12t.png


BIN
docs/intro/_images/admin13.png


BIN
docs/intro/_images/admin13t.png


BIN
docs/intro/_images/admin14.png


BIN
docs/intro/_images/admin14t.png


+ 69 - 67
docs/intro/tutorial01.txt

@@ -331,22 +331,24 @@ The first step in writing a database Web app in Django is to define your models
    the :ref:`DRY Principle <dry>`. The goal is to define your data model in one
    the :ref:`DRY Principle <dry>`. The goal is to define your data model in one
    place and automatically derive things from it.
    place and automatically derive things from it.
 
 
-In our simple poll app, we'll create two models: ``Poll`` and ``Choice``.
-A ``Poll`` has a question and a publication date. A ``Choice`` has two fields:
+In our simple poll app, we'll create two models: ``Question`` and ``Choice``.
+A ``Question`` has a question and a publication date. A ``Choice`` has two fields:
 the text of the choice and a vote tally. Each ``Choice`` is associated with a
 the text of the choice and a vote tally. Each ``Choice`` is associated with a
-``Poll``.
+``Question``.
 
 
 These concepts are represented by simple Python classes. Edit the
 These concepts are represented by simple Python classes. Edit the
 :file:`polls/models.py` file so it looks like this::
 :file:`polls/models.py` file so it looks like this::
 
 
     from django.db import models
     from django.db import models
 
 
-    class Poll(models.Model):
-        question = models.CharField(max_length=200)
+
+    class Question(models.Model):
+        question_text = models.CharField(max_length=200)
         pub_date = models.DateTimeField('date published')
         pub_date = models.DateTimeField('date published')
 
 
+
     class Choice(models.Model):
     class Choice(models.Model):
-        poll = models.ForeignKey(Poll)
+        question = models.ForeignKey(Question)
         choice_text = models.CharField(max_length=200)
         choice_text = models.CharField(max_length=200)
         votes = models.IntegerField(default=0)
         votes = models.IntegerField(default=0)
 
 
@@ -359,7 +361,7 @@ class -- e.g., :class:`~django.db.models.CharField` for character fields and
 :class:`~django.db.models.DateTimeField` for datetimes. This tells Django what
 :class:`~django.db.models.DateTimeField` for datetimes. This tells Django what
 type of data each field holds.
 type of data each field holds.
 
 
-The name of each :class:`~django.db.models.Field` instance (e.g. ``question`` or
+The name of each :class:`~django.db.models.Field` instance (e.g. ``question_text`` or
 ``pub_date``) is the field's name, in machine-friendly format. You'll use this
 ``pub_date``) is the field's name, in machine-friendly format. You'll use this
 value in your Python code, and your database will use it as the column name.
 value in your Python code, and your database will use it as the column name.
 
 
@@ -367,7 +369,7 @@ You can use an optional first positional argument to a
 :class:`~django.db.models.Field` to designate a human-readable name. That's used
 :class:`~django.db.models.Field` to designate a human-readable name. That's used
 in a couple of introspective parts of Django, and it doubles as documentation.
 in a couple of introspective parts of Django, and it doubles as documentation.
 If this field isn't provided, Django will use the machine-readable name. In this
 If this field isn't provided, Django will use the machine-readable name. In this
-example, we've only defined a human-readable name for ``Poll.pub_date``. For all
+example, we've only defined a human-readable name for ``Question.pub_date``. For all
 other fields in this model, the field's machine-readable name will suffice as
 other fields in this model, the field's machine-readable name will suffice as
 its human-readable name.
 its human-readable name.
 
 
@@ -382,7 +384,7 @@ this case, we've set the :attr:`~django.db.models.Field.default` value of
 
 
 Finally, note a relationship is defined, using
 Finally, note a relationship is defined, using
 :class:`~django.db.models.ForeignKey`. That tells Django each ``Choice`` is related
 :class:`~django.db.models.ForeignKey`. That tells Django each ``Choice`` is related
-to a single ``Poll``. Django supports all the common database relationships:
+to a single ``Question``. Django supports all the common database relationships:
 many-to-ones, many-to-manys and one-to-ones.
 many-to-ones, many-to-manys and one-to-ones.
 
 
 .. _`Python path`: http://docs.python.org/tutorial/modules.html#the-module-search-path
 .. _`Python path`: http://docs.python.org/tutorial/modules.html#the-module-search-path
@@ -394,7 +396,7 @@ That small bit of model code gives Django a lot of information. With it, Django
 is able to:
 is able to:
 
 
 * Create a database schema (``CREATE TABLE`` statements) for this app.
 * Create a database schema (``CREATE TABLE`` statements) for this app.
-* Create a Python database-access API for accessing ``Poll`` and ``Choice`` objects.
+* Create a Python database-access API for accessing ``Question`` and ``Choice`` objects.
 
 
 But first we need to tell our project that the ``polls`` app is installed.
 But first we need to tell our project that the ``polls`` app is installed.
 
 
@@ -430,14 +432,14 @@ statements for the polls app):
 .. code-block:: sql
 .. code-block:: sql
 
 
     BEGIN;
     BEGIN;
-    CREATE TABLE "polls_poll" (
+    CREATE TABLE "polls_question" (
         "id" integer NOT NULL PRIMARY KEY,
         "id" integer NOT NULL PRIMARY KEY,
-        "question" varchar(200) NOT NULL,
+        "question_text" varchar(200) NOT NULL,
         "pub_date" datetime NOT NULL
         "pub_date" datetime NOT NULL
     );
     );
     CREATE TABLE "polls_choice" (
     CREATE TABLE "polls_choice" (
         "id" integer NOT NULL PRIMARY KEY,
         "id" integer NOT NULL PRIMARY KEY,
-        "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
+        "question_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
         "choice_text" varchar(200) NOT NULL,
         "choice_text" varchar(200) NOT NULL,
         "votes" integer NOT NULL
         "votes" integer NOT NULL
     );
     );
@@ -449,7 +451,7 @@ Note the following:
   example above is generated for SQLite.
   example above is generated for SQLite.
 
 
 * Table names are automatically generated by combining the name of the app
 * Table names are automatically generated by combining the name of the app
-  (``polls``) and the lowercase name of the model -- ``poll`` and
+  (``polls``) and the lowercase name of the model -- ``question`` and
   ``choice``. (You can override this behavior.)
   ``choice``. (You can override this behavior.)
 
 
 * Primary keys (IDs) are added automatically. (You can override this, too.)
 * Primary keys (IDs) are added automatically. (You can override this, too.)
@@ -537,57 +539,57 @@ the Python import path to your :file:`mysite/settings.py` file.
 
 
 Once you're in the shell, explore the :doc:`database API </topics/db/queries>`::
 Once you're in the shell, explore the :doc:`database API </topics/db/queries>`::
 
 
-    >>> from polls.models import Poll, Choice   # Import the model classes we just wrote.
+    >>> from polls.models import Question, Choice   # Import the model classes we just wrote.
 
 
-    # No polls are in the system yet.
-    >>> Poll.objects.all()
+    # No questions are in the system yet.
+    >>> Question.objects.all()
     []
     []
 
 
-    # Create a new Poll.
+    # Create a new Question.
     # Support for time zones is enabled in the default settings file, so
     # Support for time zones is enabled in the default settings file, so
     # Django expects a datetime with tzinfo for pub_date. Use timezone.now()
     # Django expects a datetime with tzinfo for pub_date. Use timezone.now()
     # instead of datetime.datetime.now() and it will do the right thing.
     # instead of datetime.datetime.now() and it will do the right thing.
     >>> from django.utils import timezone
     >>> from django.utils import timezone
-    >>> p = Poll(question="What's new?", pub_date=timezone.now())
+    >>> q = Question(question_text="What's new?", pub_date=timezone.now())
 
 
     # Save the object into the database. You have to call save() explicitly.
     # Save the object into the database. You have to call save() explicitly.
-    >>> p.save()
+    >>> q.save()
 
 
     # Now it has an ID. Note that this might say "1L" instead of "1", depending
     # Now it has an ID. Note that this might say "1L" instead of "1", depending
     # on which database you're using. That's no biggie; it just means your
     # on which database you're using. That's no biggie; it just means your
     # database backend prefers to return integers as Python long integer
     # database backend prefers to return integers as Python long integer
     # objects.
     # objects.
-    >>> p.id
+    >>> q.id
     1
     1
 
 
     # Access database columns via Python attributes.
     # Access database columns via Python attributes.
-    >>> p.question
+    >>> q.question_text
     "What's new?"
     "What's new?"
-    >>> p.pub_date
+    >>> q.pub_date
     datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
     datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
 
 
     # Change values by changing the attributes, then calling save().
     # Change values by changing the attributes, then calling save().
-    >>> p.question = "What's up?"
-    >>> p.save()
+    >>> q.question_text = "What's up?"
+    >>> q.save()
 
 
-    # objects.all() displays all the polls in the database.
-    >>> Poll.objects.all()
-    [<Poll: Poll object>]
+    # objects.all() displays all the questions in the database.
+    >>> Question.objects.all()
+    [<Question: Question object>]
 
 
 
 
-Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful representation
-of this object. Let's fix that by editing the polls model (in the
+Wait a minute. ``<Question: Question object>`` is, utterly, an unhelpful representation
+of this object. Let's fix that by editing the ``Question`` model (in the
 ``polls/models.py`` file) and adding a
 ``polls/models.py`` file) and adding a
-:meth:`~django.db.models.Model.__unicode__` method to both ``Poll`` and
+:meth:`~django.db.models.Model.__unicode__` method to both ``Question`` and
 ``Choice``. On Python 3, simply replace ``__unicode__`` by ``__str__`` in the
 ``Choice``. On Python 3, simply replace ``__unicode__`` by ``__str__`` in the
 following example::
 following example::
 
 
     from django.db import models
     from django.db import models
 
 
-    class Poll(models.Model):
+    class Question(models.Model):
         # ...
         # ...
         def __unicode__(self):  # Python 3: def __str__(self):
         def __unicode__(self):  # Python 3: def __str__(self):
-            return self.question
+            return self.question_text
 
 
     class Choice(models.Model):
     class Choice(models.Model):
         # ...
         # ...
@@ -629,7 +631,7 @@ demonstration::
     import datetime
     import datetime
     from django.utils import timezone
     from django.utils import timezone
     # ...
     # ...
-    class Poll(models.Model):
+    class Question(models.Model):
         # ...
         # ...
         def was_published_recently(self):
         def was_published_recently(self):
             return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
             return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
@@ -643,80 +645,80 @@ the :doc:`time zone support docs </topics/i18n/timezones>`.
 Save these changes and start a new Python interactive shell by running
 Save these changes and start a new Python interactive shell by running
 ``python manage.py shell`` again::
 ``python manage.py shell`` again::
 
 
-    >>> from polls.models import Poll, Choice
+    >>> from polls.models import Question, Choice
 
 
     # Make sure our __unicode__() addition worked.
     # Make sure our __unicode__() addition worked.
-    >>> Poll.objects.all()
-    [<Poll: What's up?>]
+    >>> Question.objects.all()
+    [<Question: What's up?>]
 
 
     # Django provides a rich database lookup API that's entirely driven by
     # Django provides a rich database lookup API that's entirely driven by
     # keyword arguments.
     # keyword arguments.
-    >>> Poll.objects.filter(id=1)
-    [<Poll: What's up?>]
-    >>> Poll.objects.filter(question__startswith='What')
-    [<Poll: What's up?>]
+    >>> Question.objects.filter(id=1)
+    [<Question: What's up?>]
+    >>> Question.objects.filter(question_text__startswith='What')
+    [<Question: What's up?>]
 
 
-    # Get the poll that was published this year.
+    # Get the question that was published this year.
     >>> from django.utils import timezone
     >>> from django.utils import timezone
     >>> current_year = timezone.now().year
     >>> current_year = timezone.now().year
-    >>> Poll.objects.get(pub_date__year=current_year)
-    <Poll: What's up?>
+    >>> Question.objects.get(pub_date__year=current_year)
+    <Question: What's up?>
 
 
     # Request an ID that doesn't exist, this will raise an exception.
     # Request an ID that doesn't exist, this will raise an exception.
-    >>> Poll.objects.get(id=2)
+    >>> Question.objects.get(id=2)
     Traceback (most recent call last):
     Traceback (most recent call last):
         ...
         ...
-    DoesNotExist: Poll matching query does not exist. Lookup parameters were {'id': 2}
+    DoesNotExist: Question matching query does not exist. Lookup parameters were {'id': 2}
 
 
     # Lookup by a primary key is the most common case, so Django provides a
     # Lookup by a primary key is the most common case, so Django provides a
     # shortcut for primary-key exact lookups.
     # shortcut for primary-key exact lookups.
-    # The following is identical to Poll.objects.get(id=1).
-    >>> Poll.objects.get(pk=1)
-    <Poll: What's up?>
+    # The following is identical to Question.objects.get(id=1).
+    >>> Question.objects.get(pk=1)
+    <Question: What's up?>
 
 
     # Make sure our custom method worked.
     # Make sure our custom method worked.
-    >>> p = Poll.objects.get(pk=1)
-    >>> p.was_published_recently()
+    >>> q = Question.objects.get(pk=1)
+    >>> q.was_published_recently()
     True
     True
 
 
-    # Give the Poll a couple of Choices. The create call constructs a new
+    # Give the Question a couple of Choices. The create call constructs a new
     # Choice object, does the INSERT statement, adds the choice to the set
     # Choice object, does the INSERT statement, adds the choice to the set
     # of available choices and returns the new Choice object. Django creates
     # of available choices and returns the new Choice object. Django creates
     # a set to hold the "other side" of a ForeignKey relation
     # a set to hold the "other side" of a ForeignKey relation
-    # (e.g. a poll's choices) which can be accessed via the API.
-    >>> p = Poll.objects.get(pk=1)
+    # (e.g. a question's choice) which can be accessed via the API.
+    >>> q = Question.objects.get(pk=1)
 
 
     # Display any choices from the related object set -- none so far.
     # Display any choices from the related object set -- none so far.
-    >>> p.choice_set.all()
+    >>> q.choice_set.all()
     []
     []
 
 
     # Create three choices.
     # Create three choices.
-    >>> p.choice_set.create(choice_text='Not much', votes=0)
+    >>> q.choice_set.create(choice_text='Not much', votes=0)
     <Choice: Not much>
     <Choice: Not much>
-    >>> p.choice_set.create(choice_text='The sky', votes=0)
+    >>> q.choice_set.create(choice_text='The sky', votes=0)
     <Choice: The sky>
     <Choice: The sky>
-    >>> c = p.choice_set.create(choice_text='Just hacking again', votes=0)
+    >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
 
 
-    # Choice objects have API access to their related Poll objects.
-    >>> c.poll
-    <Poll: What's up?>
+    # Choice objects have API access to their related Question objects.
+    >>> c.question
+    <Question: What's up?>
 
 
-    # And vice versa: Poll objects get access to Choice objects.
-    >>> p.choice_set.all()
+    # And vice versa: Question objects get access to Choice objects.
+    >>> q.choice_set.all()
     [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
     [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
-    >>> p.choice_set.count()
+    >>> q.choice_set.count()
     3
     3
 
 
     # The API automatically follows relationships as far as you need.
     # The API automatically follows relationships as far as you need.
     # Use double underscores to separate relationships.
     # Use double underscores to separate relationships.
     # This works as many levels deep as you want; there's no limit.
     # This works as many levels deep as you want; there's no limit.
-    # Find all Choices for any poll whose pub_date is in this year
+    # Find all Choices for any question whose pub_date is in this year
     # (reusing the 'current_year' variable we created above).
     # (reusing the 'current_year' variable we created above).
-    >>> Choice.objects.filter(poll__pub_date__year=current_year)
+    >>> Choice.objects.filter(question__pub_date__year=current_year)
     [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
     [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
 
 
     # Let's delete one of the choices. Use delete() for that.
     # Let's delete one of the choices. Use delete() for that.
-    >>> c = p.choice_set.filter(choice_text__startswith='Just hacking')
+    >>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
     >>> c.delete()
     >>> c.delete()
 
 
 For more information on model relations, see :doc:`Accessing related objects
 For more information on model relations, see :doc:`Accessing related objects

+ 65 - 59
docs/intro/tutorial02.txt

@@ -65,7 +65,7 @@ tutorial, remember?  If you didn't create one or forgot the password you can
 
 
 You should see the Django admin index page:
 You should see the Django admin index page:
 
 
-.. image:: _images/admin02t.png
+.. image:: _images/admin02.png
    :alt: Django admin index page
    :alt: Django admin index page
 
 
 You should see a few types of editable content: groups and users. They are
 You should see a few types of editable content: groups and users. They are
@@ -77,39 +77,39 @@ Make the poll app modifiable in the admin
 
 
 But where's our poll app? It's not displayed on the admin index page.
 But where's our poll app? It's not displayed on the admin index page.
 
 
-Just one thing to do: we need to tell the admin that ``Poll``
+Just one thing to do: we need to tell the admin that ``Question``
 objects have an admin interface. To do this, open the :file:`polls/admin.py`
 objects have an admin interface. To do this, open the :file:`polls/admin.py`
 file, and edit it to look like this::
 file, and edit it to look like this::
 
 
     from django.contrib import admin
     from django.contrib import admin
-    from polls.models import Poll
+    from polls.models import Question
 
 
-    admin.site.register(Poll)
+    admin.site.register(Question)
 
 
 Explore the free admin functionality
 Explore the free admin functionality
 ====================================
 ====================================
 
 
-Now that we've registered ``Poll``, Django knows that it should be displayed on
+Now that we've registered ``Question``, Django knows that it should be displayed on
 the admin index page:
 the admin index page:
 
 
 .. image:: _images/admin03t.png
 .. image:: _images/admin03t.png
    :alt: Django admin index page, now with polls displayed
    :alt: Django admin index page, now with polls displayed
 
 
-Click "Polls." Now you're at the "change list" page for polls. This page
-displays all the polls in the database and lets you choose one to change it.
-There's the "What's up?" poll we created in the first tutorial:
+Click "Questions". Now you're at the "change list" page for questions. This page
+displays all the question in the database and lets you choose one to change it.
+There's the "What's up?" question we created in the first tutorial:
 
 
 .. image:: _images/admin04t.png
 .. image:: _images/admin04t.png
    :alt: Polls change list page
    :alt: Polls change list page
 
 
-Click the "What's up?" poll to edit it:
+Click the "What's up?" question to edit it:
 
 
 .. image:: _images/admin05t.png
 .. image:: _images/admin05t.png
-   :alt: Editing form for poll object
+   :alt: Editing form for question object
 
 
 Things to note here:
 Things to note here:
 
 
-* The form is automatically generated from the ``Poll`` model.
+* The form is automatically generated from the ``Question`` model.
 
 
 * The different model field types (:class:`~django.db.models.DateTimeField`,
 * The different model field types (:class:`~django.db.models.DateTimeField`,
   :class:`~django.db.models.CharField`) correspond to the appropriate HTML
   :class:`~django.db.models.CharField`) correspond to the appropriate HTML
@@ -134,7 +134,7 @@ The bottom part of the page gives you a couple of options:
 * Delete -- Displays a delete confirmation page.
 * Delete -- Displays a delete confirmation page.
 
 
 If the value of "Date published" doesn't match the time when you created the
 If the value of "Date published" doesn't match the time when you created the
-poll in Tutorial 1, it probably means you forgot to set the correct value for
+question in Tutorial 1, it probably means you forgot to set the correct value for
 the :setting:`TIME_ZONE` setting. Change it, reload the page and check that
 the :setting:`TIME_ZONE` setting. Change it, reload the page and check that
 the correct value appears.
 the correct value appears.
 
 
@@ -144,27 +144,28 @@ You'll see a page listing all changes made to this object via the Django admin,
 with the timestamp and username of the person who made the change:
 with the timestamp and username of the person who made the change:
 
 
 .. image:: _images/admin06t.png
 .. image:: _images/admin06t.png
-   :alt: History page for poll object
+   :alt: History page for question object
 
 
 Customize the admin form
 Customize the admin form
 ========================
 ========================
 
 
 Take a few minutes to marvel at all the code you didn't have to write. By
 Take a few minutes to marvel at all the code you didn't have to write. By
-registering the Poll model with ``admin.site.register(Poll)``, Django was able
-to construct a default form representation. Often, you'll want to customize how
-the admin form looks and works. You'll do this by telling Django the options
-you want when you register the object.
+registering the ``Question`` model with ``admin.site.register(Question)``,
+Django was able to construct a default form representation. Often, you'll want
+to customize how the admin form looks and works. You'll do this by telling
+Django the options you want when you register the object.
 
 
 Let's see how this works by re-ordering the fields on the edit form. Replace
 Let's see how this works by re-ordering the fields on the edit form. Replace
-the ``admin.site.register(Poll)`` line with::
+the ``admin.site.register(Question)`` line with::
 
 
     from django.contrib import admin
     from django.contrib import admin
-    from polls.models import Poll
+    from polls.models import Question
 
 
-    class PollAdmin(admin.ModelAdmin):
-        fields = ['pub_date', 'question']
 
 
-    admin.site.register(Poll, PollAdmin)
+    class QuestionAdmin(admin.ModelAdmin):
+        fields = ['pub_date', 'question_text']
+
+    admin.site.register(Question, QuestionAdmin)
 
 
 You'll follow this pattern -- create a model admin object, then pass it as the
 You'll follow this pattern -- create a model admin object, then pass it as the
 second argument to ``admin.site.register()`` -- any time you need to change the
 second argument to ``admin.site.register()`` -- any time you need to change the
@@ -183,15 +184,16 @@ And speaking of forms with dozens of fields, you might want to split the form
 up into fieldsets::
 up into fieldsets::
 
 
     from django.contrib import admin
     from django.contrib import admin
-    from polls.models import Poll
+    from polls.models import Question
+
 
 
-    class PollAdmin(admin.ModelAdmin):
+    class QuestionAdmin(admin.ModelAdmin):
         fieldsets = [
         fieldsets = [
-            (None,               {'fields': ['question']}),
+            (None,               {'fields': ['question_text']}),
             ('Date information', {'fields': ['pub_date']}),
             ('Date information', {'fields': ['pub_date']}),
         ]
         ]
 
 
-    admin.site.register(Poll, PollAdmin)
+    admin.site.register(Question, QuestionAdmin)
 
 
 The first element of each tuple in ``fieldsets`` is the title of the fieldset.
 The first element of each tuple in ``fieldsets`` is the title of the fieldset.
 Here's what our form looks like now:
 Here's what our form looks like now:
@@ -205,11 +207,12 @@ This is useful when you have a long form that contains a number of fields that
 aren't commonly used::
 aren't commonly used::
 
 
         from django.contrib import admin
         from django.contrib import admin
-        from polls.models import Poll
+        from polls.models import Question
+
 
 
-        class PollAdmin(admin.ModelAdmin):
+        class QuestionAdmin(admin.ModelAdmin):
             fieldsets = [
             fieldsets = [
-                (None,               {'fields': ['question']}),
+                (None,               {'fields': ['question_text']}),
                 ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
                 ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
             ]
             ]
 
 
@@ -219,13 +222,13 @@ aren't commonly used::
 Adding related objects
 Adding related objects
 ======================
 ======================
 
 
-OK, we have our Poll admin page. But a ``Poll`` has multiple ``Choices``, and
+OK, we have our Question admin page. But a ``Question`` has multiple ``Choices``, and
 the admin page doesn't display choices.
 the admin page doesn't display choices.
 
 
 Yet.
 Yet.
 
 
 There are two ways to solve this problem. The first is to register ``Choice``
 There are two ways to solve this problem. The first is to register ``Choice``
-with the admin just as we did with ``Poll``. That's easy::
+with the admin just as we did with ``Question``. That's easy::
 
 
     from django.contrib import admin
     from django.contrib import admin
     from polls.models import Choice
     from polls.models import Choice
@@ -238,48 +241,51 @@ looks like this:
 .. image:: _images/admin10.png
 .. image:: _images/admin10.png
    :alt: Choice admin page
    :alt: Choice admin page
 
 
-In that form, the "Poll" field is a select box containing every poll in the
+In that form, the "Question" field is a select box containing every question in the
 database. Django knows that a :class:`~django.db.models.ForeignKey` should be
 database. Django knows that a :class:`~django.db.models.ForeignKey` should be
-represented in the admin as a ``<select>`` box. In our case, only one poll
+represented in the admin as a ``<select>`` box. In our case, only one question
 exists at this point.
 exists at this point.
 
 
-Also note the "Add Another" link next to "Poll." Every object with a
+Also note the "Add Another" link next to "Question." Every object with a
 ``ForeignKey`` relationship to another gets this for free. When you click "Add
 ``ForeignKey`` relationship to another gets this for free. When you click "Add
-Another," you'll get a popup window with the "Add poll" form. If you add a poll
-in that window and click "Save," Django will save the poll to the database and
+Another," you'll get a popup window with the "Add question" form. If you add a question
+in that window and click "Save," Django will save the question to the database and
 dynamically add it as the selected choice on the "Add choice" form you're
 dynamically add it as the selected choice on the "Add choice" form you're
 looking at.
 looking at.
 
 
 But, really, this is an inefficient way of adding ``Choice`` objects to the system.
 But, really, this is an inefficient way of adding ``Choice`` objects to the system.
 It'd be better if you could add a bunch of Choices directly when you create the
 It'd be better if you could add a bunch of Choices directly when you create the
-``Poll`` object. Let's make that happen.
+``Question`` object. Let's make that happen.
 
 
-Remove the ``register()`` call for the ``Choice`` model. Then, edit the ``Poll``
+Remove the ``register()`` call for the ``Choice`` model. Then, edit the ``Question``
 registration code to read::
 registration code to read::
 
 
     from django.contrib import admin
     from django.contrib import admin
-    from polls.models import Choice, Poll
+    from polls.models import Choice, Question
+
 
 
     class ChoiceInline(admin.StackedInline):
     class ChoiceInline(admin.StackedInline):
         model = Choice
         model = Choice
         extra = 3
         extra = 3
 
 
-    class PollAdmin(admin.ModelAdmin):
+
+    class QuestionAdmin(admin.ModelAdmin):
         fieldsets = [
         fieldsets = [
-            (None,               {'fields': ['question']}),
-            ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
+            (None,               {'fields': ['question_text']}),
+            ('Date information', {'fields': ['pub_date'],
+                                  'classes': ['collapse']}),
         ]
         ]
         inlines = [ChoiceInline]
         inlines = [ChoiceInline]
 
 
-    admin.site.register(Poll, PollAdmin)
+    admin.site.register(Question, QuestionAdmin)
 
 
-This tells Django: "``Choice`` objects are edited on the ``Poll`` admin page. By
+This tells Django: "``Choice`` objects are edited on the ``Question`` admin page. By
 default, provide enough fields for 3 choices."
 default, provide enough fields for 3 choices."
 
 
-Load the "Add poll" page to see how that looks:
+Load the "Add question" page to see how that looks:
 
 
 .. image:: _images/admin11t.png
 .. image:: _images/admin11t.png
-   :alt: Add poll page now has choices on it
+   :alt: Add question page now has choices on it
 
 
 It works like this: There are three slots for related Choices -- as specified
 It works like this: There are three slots for related Choices -- as specified
 by ``extra`` -- and each time you come back to the "Change" page for an
 by ``extra`` -- and each time you come back to the "Change" page for an
@@ -305,7 +311,7 @@ With that ``TabularInline`` (instead of ``StackedInline``), the
 related objects are displayed in a more compact, table-based format:
 related objects are displayed in a more compact, table-based format:
 
 
 .. image:: _images/admin12t.png
 .. image:: _images/admin12t.png
-   :alt: Add poll page now has more compact choices
+   :alt: Add question page now has more compact choices
 
 
 Note that there is an extra "Delete?" column that allows removing rows added
 Note that there is an extra "Delete?" column that allows removing rows added
 using the "Add Another Choice" button and rows that have already been saved.
 using the "Add Another Choice" button and rows that have already been saved.
@@ -313,8 +319,8 @@ using the "Add Another Choice" button and rows that have already been saved.
 Customize the admin change list
 Customize the admin change list
 ===============================
 ===============================
 
 
-Now that the Poll admin page is looking good, let's make some tweaks to the
-"change list" page -- the one that displays all the polls in the system.
+Now that the Question admin page is looking good, let's make some tweaks to the
+"change list" page -- the one that displays all the questions in the system.
 
 
 Here's what it looks like at this point:
 Here's what it looks like at this point:
 
 
@@ -326,18 +332,18 @@ more helpful if we could display individual fields. To do that, use the
 ``list_display`` admin option, which is a tuple of field names to display, as
 ``list_display`` admin option, which is a tuple of field names to display, as
 columns, on the change list page for the object::
 columns, on the change list page for the object::
 
 
-    class PollAdmin(admin.ModelAdmin):
+    class QuestionAdmin(admin.ModelAdmin):
         # ...
         # ...
-        list_display = ('question', 'pub_date')
+        list_display = ('question_text', 'pub_date')
 
 
 Just for good measure, let's also include the ``was_published_recently`` custom
 Just for good measure, let's also include the ``was_published_recently`` custom
 method from Tutorial 1::
 method from Tutorial 1::
 
 
-    class PollAdmin(admin.ModelAdmin):
+    class QuestionAdmin(admin.ModelAdmin):
         # ...
         # ...
-        list_display = ('question', 'pub_date', 'was_published_recently')
+        list_display = ('question_text', 'pub_date', 'was_published_recently')
 
 
-Now the poll change list page looks like this:
+Now the question change list page looks like this:
 
 
 .. image:: _images/admin13t.png
 .. image:: _images/admin13t.png
    :alt: Polls change list page, updated
    :alt: Polls change list page, updated
@@ -352,7 +358,7 @@ representation of the output.
 You can improve that by giving that method (in :file:`polls/models.py`) a few
 You can improve that by giving that method (in :file:`polls/models.py`) a few
 attributes, as follows::
 attributes, as follows::
 
 
-    class Poll(models.Model):
+    class Question(models.Model):
         # ...
         # ...
         def was_published_recently(self):
         def was_published_recently(self):
             return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
             return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
@@ -360,8 +366,8 @@ attributes, as follows::
         was_published_recently.boolean = True
         was_published_recently.boolean = True
         was_published_recently.short_description = 'Published recently?'
         was_published_recently.short_description = 'Published recently?'
 
 
-Edit your :file:`polls/admin.py` file again and add an improvement to the Poll
-change list page: Filters. Add the following line to ``PollAdmin``::
+Edit your :file:`polls/admin.py` file again and add an improvement to the Question
+change list page: Filters. Add the following line to ``QuestionAdmin``::
 
 
     list_filter = ['pub_date']
     list_filter = ['pub_date']
 
 
@@ -378,10 +384,10 @@ knows to give appropriate filter options: "Any date," "Today," "Past 7 days,"
 
 
 This is shaping up well. Let's add some search capability::
 This is shaping up well. Let's add some search capability::
 
 
-    search_fields = ['question']
+    search_fields = ['question_text']
 
 
 That adds a search box at the top of the change list. When somebody enters
 That adds a search box at the top of the change list. When somebody enters
-search terms, Django will search the ``question`` field. You can use as many
+search terms, Django will search the ``question_text`` field. You can use as many
 fields as you'd like -- although because it uses a ``LIKE`` query behind the
 fields as you'd like -- although because it uses a ``LIKE`` query behind the
 scenes, keep it reasonable, to keep your database happy.
 scenes, keep it reasonable, to keep your database happy.
 
 

+ 66 - 61
docs/intro/tutorial03.txt

@@ -29,15 +29,15 @@ application, you might have the following views:
 
 
 In our poll application, we'll have the following four views:
 In our poll application, we'll have the following four views:
 
 
-* Poll "index" page -- displays the latest few polls.
+* Question "index" page -- displays the latest few questions.
 
 
-* Poll "detail" page -- displays a poll question, with no results but
+* Question "detail" page -- displays a question text, with no results but
   with a form to vote.
   with a form to vote.
 
 
-* Poll "results" page -- displays results for a particular poll.
+* Question "results" page -- displays results for a particular question.
 
 
 * Vote action -- handles voting for a particular choice in a particular
 * Vote action -- handles voting for a particular choice in a particular
-  poll.
+  question.
 
 
 In Django, web pages and other content are delivered by views. Each view is
 In Django, web pages and other content are delivered by views. Each view is
 represented by a simple Python function (or method, in the case of class-based
 represented by a simple Python function (or method, in the case of class-based
@@ -66,8 +66,9 @@ and put the following Python code in it::
 
 
     from django.http import HttpResponse
     from django.http import HttpResponse
 
 
+
     def index(request):
     def index(request):
-        return HttpResponse("Hello, world. You're at the poll index.")
+        return HttpResponse("Hello, world. You're at the polls index.")
 
 
 This is the simplest view possible in Django. To call the view, we need to map
 This is the simplest view possible in Django. To call the view, we need to map
 it to a URL - and for this we need a URLconf.
 it to a URL - and for this we need a URLconf.
@@ -109,7 +110,7 @@ with::
 
 
 You have now wired an ``index`` view into the URLconf. Go to
 You have now wired an ``index`` view into the URLconf. Go to
 http://localhost:8000/polls/ in your browser, and you should see the text
 http://localhost:8000/polls/ in your browser, and you should see the text
-"*Hello, world. You're at the poll index.*", which you defined in the
+"*Hello, world. You're at the polls index.*", which you defined in the
 ``index`` view.
 ``index`` view.
 
 
 The :func:`~django.conf.urls.url` function is passed four arguments, two
 The :func:`~django.conf.urls.url` function is passed four arguments, two
@@ -173,14 +174,15 @@ Writing more views
 Now let's add a few more views to ``polls/views.py``. These views are
 Now let's add a few more views to ``polls/views.py``. These views are
 slightly different, because they take an argument::
 slightly different, because they take an argument::
 
 
-    def detail(request, poll_id):
-        return HttpResponse("You're looking at poll %s." % poll_id)
+    def detail(request, question_id):
+        return HttpResponse("You're looking at question %s." % question_id)
 
 
-    def results(request, poll_id):
-        return HttpResponse("You're looking at the results of poll %s." % poll_id)
+    def results(request, question_id):
+        response = "You're looking at the results of question %s."
+        return HttpResponse(response % question_id)
 
 
-    def vote(request, poll_id):
-        return HttpResponse("You're voting on poll %s." % poll_id)
+    def vote(request, question_id):
+        return HttpResponse("You're voting on question %s." % question_id)
 
 
 Wire these new views into the ``polls.urls`` module by adding the following
 Wire these new views into the ``polls.urls`` module by adding the following
 :func:`~django.conf.urls.url` calls::
 :func:`~django.conf.urls.url` calls::
@@ -193,11 +195,11 @@ Wire these new views into the ``polls.urls`` module by adding the following
         # ex: /polls/
         # ex: /polls/
         url(r'^$', views.index, name='index'),
         url(r'^$', views.index, name='index'),
         # ex: /polls/5/
         # ex: /polls/5/
-        url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
+        url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'),
         # ex: /polls/5/results/
         # ex: /polls/5/results/
-        url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
+        url(r'^(?P<question_id>\d+)/results/$', views.results, name='results'),
         # ex: /polls/5/vote/
         # ex: /polls/5/vote/
-        url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
+        url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
     )
     )
 
 
 Take a look in your browser, at "/polls/34/". It'll run the ``detail()``
 Take a look in your browser, at "/polls/34/". It'll run the ``detail()``
@@ -229,14 +231,14 @@ Here's what happens if a user goes to "/polls/34/" in this system:
 
 
 * Then, Django will strip off the matching text (``"polls/"``) and send the
 * Then, Django will strip off the matching text (``"polls/"``) and send the
   remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
   remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
-  further processing which matches ``r'^(?P<poll_id>\d+)/$'`` resulting in a
+  further processing which matches ``r'^(?P<question_id>\d+)/$'`` resulting in a
   call to the ``detail()`` view like so::
   call to the ``detail()`` view like so::
 
 
-    detail(request=<HttpRequest object>, poll_id='34')
+    detail(request=<HttpRequest object>, question_id='34')
 
 
-The ``poll_id='34'`` part comes from ``(?P<poll_id>\d+)``. Using parentheses
+The ``question_id='34'`` part comes from ``(?P<question_id>\d+)``. Using parentheses
 around a pattern "captures" the text matched by that pattern and sends it as an
 around a pattern "captures" the text matched by that pattern and sends it as an
-argument to the view function; ``?P<poll_id>`` defines the name that will
+argument to the view function; ``?P<question_id>`` defines the name that will
 be used to identify the matched pattern; and ``\d+`` is a regular expression to
 be used to identify the matched pattern; and ``\d+`` is a regular expression to
 match a sequence of digits (i.e., a number).
 match a sequence of digits (i.e., a number).
 
 
@@ -271,11 +273,12 @@ commas, according to publication date::
 
 
     from django.http import HttpResponse
     from django.http import HttpResponse
 
 
-    from polls.models import Poll
+    from polls.models import Question
+
 
 
     def index(request):
     def index(request):
-        latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
-        output = ', '.join([p.question for p in latest_poll_list])
+        latest_question_list = Question.objects.order_by('-pub_date')[:5]
+        output = ', '.join([p.question_text for p in latest_question_list])
         return HttpResponse(output)
         return HttpResponse(output)
 
 
 There's a problem here, though: the page's design is hard-coded in the view. If
 There's a problem here, though: the page's design is hard-coded in the view. If
@@ -326,10 +329,10 @@ Put the following code in that template:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    {% if latest_poll_list %}
+    {% if latest_question_list %}
         <ul>
         <ul>
-        {% for poll in latest_poll_list %}
-            <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
+        {% for question in latest_question_list %}
+            <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
         {% endfor %}
         {% endfor %}
         </ul>
         </ul>
     {% else %}
     {% else %}
@@ -341,13 +344,14 @@ Now let's update our ``index`` view in ``polls/views.py`` to use the template::
     from django.http import HttpResponse
     from django.http import HttpResponse
     from django.template import RequestContext, loader
     from django.template import RequestContext, loader
 
 
-    from polls.models import Poll
+    from polls.models import Question
+
 
 
     def index(request):
     def index(request):
-        latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
+        latest_question_list = Question.objects.order_by('-pub_date')[:5]
         template = loader.get_template('polls/index.html')
         template = loader.get_template('polls/index.html')
         context = RequestContext(request, {
         context = RequestContext(request, {
-            'latest_poll_list': latest_poll_list,
+            'latest_question_list': latest_question_list,
         })
         })
         return HttpResponse(template.render(context))
         return HttpResponse(template.render(context))
 
 
@@ -356,8 +360,8 @@ context. The context is a dictionary mapping template variable names to Python
 objects.
 objects.
 
 
 Load the page by pointing your browser at "/polls/", and you should see a
 Load the page by pointing your browser at "/polls/", and you should see a
-bulleted-list containing the "What's up" poll from Tutorial 1. The link points
-to the poll's detail page.
+bulleted-list containing the "What's up" question from Tutorial 1. The link points
+to the question's detail page.
 
 
 A shortcut: :func:`~django.shortcuts.render`
 A shortcut: :func:`~django.shortcuts.render`
 --------------------------------------------
 --------------------------------------------
@@ -369,11 +373,12 @@ rewritten::
 
 
     from django.shortcuts import render
     from django.shortcuts import render
 
 
-    from polls.models import Poll
+    from polls.models import Question
+
 
 
     def index(request):
     def index(request):
-        latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
-        context = {'latest_poll_list': latest_poll_list}
+        latest_question_list = Question.objects.all().order_by('-pub_date')[:5]
+        context = {'latest_question_list': latest_question_list}
         return render(request, 'polls/index.html', context)
         return render(request, 'polls/index.html', context)
 
 
 Note that once we've done this in all these views, we no longer need to import
 Note that once we've done this in all these views, we no longer need to import
@@ -389,29 +394,29 @@ object of the given template rendered with the given context.
 Raising a 404 error
 Raising a 404 error
 ===================
 ===================
 
 
-Now, let's tackle the poll detail view -- the page that displays the question
+Now, let's tackle the question detail view -- the page that displays the question text
 for a given poll. Here's the view::
 for a given poll. Here's the view::
 
 
     from django.http import Http404
     from django.http import Http404
     from django.shortcuts import render
     from django.shortcuts import render
 
 
-    from polls.models import Poll
+    from polls.models import Question
     # ...
     # ...
-    def detail(request, poll_id):
+    def detail(request, question_id):
         try:
         try:
-            poll = Poll.objects.get(pk=poll_id)
-        except Poll.DoesNotExist:
+            question = Question.objects.get(pk=question_id)
+        except Question.DoesNotExist:
             raise Http404
             raise Http404
-        return render(request, 'polls/detail.html', {'poll': poll})
+        return render(request, 'polls/detail.html', {'question': question})
 
 
 The new concept here: The view raises the :exc:`~django.http.Http404` exception
 The new concept here: The view raises the :exc:`~django.http.Http404` exception
-if a poll with the requested ID doesn't exist.
+if a question with the requested ID doesn't exist.
 
 
 We'll discuss what you could put in that ``polls/detail.html`` template a bit
 We'll discuss what you could put in that ``polls/detail.html`` template a bit
 later, but if you'd like to quickly get the above example working, a file
 later, but if you'd like to quickly get the above example working, a file
 containing just::
 containing just::
 
 
-    {{ poll }}
+    {{ question }}
 
 
 will get you started for now.
 will get you started for now.
 
 
@@ -424,11 +429,11 @@ provides a shortcut. Here's the ``detail()`` view, rewritten::
 
 
     from django.shortcuts import render, get_object_or_404
     from django.shortcuts import render, get_object_or_404
 
 
-    from polls.models import Poll
+    from polls.models import Question
     # ...
     # ...
-    def detail(request, poll_id):
-        poll = get_object_or_404(Poll, pk=poll_id)
-        return render(request, 'polls/detail.html', {'poll': poll})
+    def detail(request, question_id):
+        question = get_object_or_404(Question, pk=question_id)
+        return render(request, 'polls/detail.html', {'question': question})
 
 
 The :func:`~django.shortcuts.get_object_or_404` function takes a Django model
 The :func:`~django.shortcuts.get_object_or_404` function takes a Django model
 as its first argument and an arbitrary number of keyword arguments, which it
 as its first argument and an arbitrary number of keyword arguments, which it
@@ -458,27 +463,27 @@ Use the template system
 =======================
 =======================
 
 
 Back to the ``detail()`` view for our poll application. Given the context
 Back to the ``detail()`` view for our poll application. Given the context
-variable ``poll``, here's what the ``polls/detail.html`` template might look
+variable ``question``, here's what the ``polls/detail.html`` template might look
 like:
 like:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <h1>{{ poll.question }}</h1>
+    <h1>{{ question.question_text }}</h1>
     <ul>
     <ul>
-    {% for choice in poll.choice_set.all %}
+    {% for choice in question.choice_set.all %}
         <li>{{ choice.choice_text }}</li>
         <li>{{ choice.choice_text }}</li>
     {% endfor %}
     {% endfor %}
     </ul>
     </ul>
 
 
 The template system uses dot-lookup syntax to access variable attributes. In
 The template system uses dot-lookup syntax to access variable attributes. In
-the example of ``{{ poll.question }}``, first Django does a dictionary lookup
-on the object ``poll``. Failing that, it tries an attribute lookup -- which
+the example of ``{{ question.question_text }}``, first Django does a dictionary lookup
+on the object ``question``. Failing that, it tries an attribute lookup -- which
 works, in this case. If attribute lookup had failed, it would've tried a
 works, in this case. If attribute lookup had failed, it would've tried a
 list-index lookup.
 list-index lookup.
 
 
 Method-calling happens in the :ttag:`{% for %}<for>` loop:
 Method-calling happens in the :ttag:`{% for %}<for>` loop:
-``poll.choice_set.all`` is interpreted as the Python code
-``poll.choice_set.all()``, which returns an iterable of ``Choice`` objects and is
+``question.choice_set.all`` is interpreted as the Python code
+``question.choice_set.all()``, which returns an iterable of ``Choice`` objects and is
 suitable for use in the :ttag:`{% for %}<for>` tag.
 suitable for use in the :ttag:`{% for %}<for>` tag.
 
 
 See the :doc:`template guide </topics/templates>` for more about templates.
 See the :doc:`template guide </topics/templates>` for more about templates.
@@ -486,12 +491,12 @@ See the :doc:`template guide </topics/templates>` for more about templates.
 Removing hardcoded URLs in templates
 Removing hardcoded URLs in templates
 ====================================
 ====================================
 
 
-Remember, when we wrote the link to a poll in the ``polls/index.html``
+Remember, when we wrote the link to a question in the ``polls/index.html``
 template, the link was partially hardcoded like this:
 template, the link was partially hardcoded like this:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
+    <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
 
 
 The problem with this hardcoded, tightly-coupled approach is that it becomes
 The problem with this hardcoded, tightly-coupled approach is that it becomes
 challenging to change URLs on projects with a lot of templates. However, since
 challenging to change URLs on projects with a lot of templates. However, since
@@ -501,12 +506,12 @@ defined in your url configurations by using the ``{% url %}`` template tag:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>
+    <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
 
 
 .. note::
 .. note::
 
 
-    If ``{% url 'detail' poll.id %}`` (with quotes) doesn't work, but
-    ``{% url detail poll.id %}`` (without quotes) does, that means you're
+    If ``{% url 'detail' question.id %}`` (with quotes) doesn't work, but
+    ``{% url detail question.id %}`` (without quotes) does, that means you're
     using a version of Django < 1.5. In this case, add the following
     using a version of Django < 1.5. In this case, add the following
     declaration at the top of your template:
     declaration at the top of your template:
 
 
@@ -520,7 +525,7 @@ defined below::
 
 
     ...
     ...
     # the 'name' value as called by the {% url %} template tag
     # the 'name' value as called by the {% url %} template tag
-    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
+    url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'),
     ...
     ...
 
 
 If you want to change the URL of the polls detail view to something else,
 If you want to change the URL of the polls detail view to something else,
@@ -529,7 +534,7 @@ template (or templates) you would change it in ``polls/urls.py``::
 
 
     ...
     ...
     # added the word 'specifics'
     # added the word 'specifics'
-    url(r'^specifics/(?P<poll_id>\d+)/$', views.detail, name='detail'),
+    url(r'^specifics/(?P<question_id>\d+)/$', views.detail, name='detail'),
     ...
     ...
 
 
 Namespacing URL names
 Namespacing URL names
@@ -560,13 +565,13 @@ Now change your ``polls/index.html`` template from:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>
+    <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
 
 
 to point at the namespaced detail view:
 to point at the namespaced detail view:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>
+    <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
 
 
 When you're comfortable with writing views, read :doc:`part 4 of this tutorial
 When you're comfortable with writing views, read :doc:`part 4 of this tutorial
 </intro/tutorial04>` to learn about simple form processing and generic views.
 </intro/tutorial04>` to learn about simple form processing and generic views.

+ 40 - 37
docs/intro/tutorial04.txt

@@ -14,13 +14,13 @@ tutorial, so that the template contains an HTML ``<form>`` element:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <h1>{{ poll.question }}</h1>
+    <h1>{{ question.question_text }}</h1>
 
 
     {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
     {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
 
 
-    <form action="{% url 'polls:vote' poll.id %}" method="post">
+    <form action="{% url 'polls:vote' question.id %}" method="post">
     {% csrf_token %}
     {% csrf_token %}
-    {% for choice in poll.choice_set.all %}
+    {% for choice in question.choice_set.all %}
         <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
         <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
         <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
         <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
     {% endfor %}
     {% endfor %}
@@ -29,13 +29,13 @@ tutorial, so that the template contains an HTML ``<form>`` element:
 
 
 A quick rundown:
 A quick rundown:
 
 
-* The above template displays a radio button for each poll choice. The
-  ``value`` of each radio button is the associated poll choice's ID. The
+* The above template displays a radio button for each question choice. The
+  ``value`` of each radio button is the associated question choice's ID. The
   ``name`` of each radio button is ``"choice"``. That means, when somebody
   ``name`` of each radio button is ``"choice"``. That means, when somebody
   selects one of the radio buttons and submits the form, it'll send the
   selects one of the radio buttons and submits the form, it'll send the
   POST data ``choice=3``. This is the basic concept of HTML forms.
   POST data ``choice=3``. This is the basic concept of HTML forms.
 
 
-* We set the form's ``action`` to ``{% url 'polls:vote' poll.id %}``, and we
+* We set the form's ``action`` to ``{% url 'polls:vote' question.id %}``, and we
   set ``method="post"``. Using ``method="post"`` (as opposed to
   set ``method="post"``. Using ``method="post"`` (as opposed to
   ``method="get"``) is very important, because the act of submitting this
   ``method="get"``) is very important, because the act of submitting this
   form will alter data server-side. Whenever you create a form that alters
   form will alter data server-side. Whenever you create a form that alters
@@ -56,7 +56,7 @@ Now, let's create a Django view that handles the submitted data and does
 something with it. Remember, in :doc:`Tutorial 3 </intro/tutorial03>`, we
 something with it. Remember, in :doc:`Tutorial 3 </intro/tutorial03>`, we
 created a URLconf for the polls application that includes this line::
 created a URLconf for the polls application that includes this line::
 
 
-    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
+    url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
 
 
 We also created a dummy implementation of the ``vote()`` function. Let's
 We also created a dummy implementation of the ``vote()`` function. Let's
 create a real version. Add the following to ``polls/views.py``::
 create a real version. Add the following to ``polls/views.py``::
@@ -64,16 +64,16 @@ create a real version. Add the following to ``polls/views.py``::
     from django.shortcuts import get_object_or_404, render
     from django.shortcuts import get_object_or_404, render
     from django.http import HttpResponseRedirect, HttpResponse
     from django.http import HttpResponseRedirect, HttpResponse
     from django.core.urlresolvers import reverse
     from django.core.urlresolvers import reverse
-    from polls.models import Choice, Poll
+    from polls.models import Choice, Question
     # ...
     # ...
-    def vote(request, poll_id):
-        p = get_object_or_404(Poll, pk=poll_id)
+    def vote(request, question_id):
+        p = get_object_or_404(Question, pk=question_id)
         try:
         try:
             selected_choice = p.choice_set.get(pk=request.POST['choice'])
             selected_choice = p.choice_set.get(pk=request.POST['choice'])
         except (KeyError, Choice.DoesNotExist):
         except (KeyError, Choice.DoesNotExist):
-            # Redisplay the poll voting form.
+            # Redisplay the question voting form.
             return render(request, 'polls/detail.html', {
             return render(request, 'polls/detail.html', {
-                'poll': p,
+                'question': p,
                 'error_message': "You didn't select a choice.",
                 'error_message': "You didn't select a choice.",
             })
             })
         else:
         else:
@@ -100,7 +100,7 @@ This code includes a few things we haven't covered yet in this tutorial:
 
 
 * ``request.POST['choice']`` will raise :exc:`~exceptions.KeyError` if
 * ``request.POST['choice']`` will raise :exc:`~exceptions.KeyError` if
   ``choice`` wasn't provided in POST data. The above code checks for
   ``choice`` wasn't provided in POST data. The above code checks for
-  :exc:`~exceptions.KeyError` and redisplays the poll form with an error
+  :exc:`~exceptions.KeyError` and redisplays the question form with an error
   message if ``choice`` isn't given.
   message if ``choice`` isn't given.
 
 
 * After incrementing the choice count, the code returns an
 * After incrementing the choice count, the code returns an
@@ -133,14 +133,15 @@ As mentioned in Tutorial 3, ``request`` is a :class:`~django.http.HttpRequest`
 object. For more on :class:`~django.http.HttpRequest` objects, see the
 object. For more on :class:`~django.http.HttpRequest` objects, see the
 :doc:`request and response documentation </ref/request-response>`.
 :doc:`request and response documentation </ref/request-response>`.
 
 
-After somebody votes in a poll, the ``vote()`` view redirects to the results
-page for the poll. Let's write that view::
+After somebody votes in a question, the ``vote()`` view redirects to the results
+page for the question. Let's write that view::
 
 
     from django.shortcuts import get_object_or_404, render
     from django.shortcuts import get_object_or_404, render
 
 
-    def results(request, poll_id):
-        poll = get_object_or_404(Poll, pk=poll_id)
-        return render(request, 'polls/results.html', {'poll': poll})
+
+    def results(request, question_id):
+        question = get_object_or_404(Question, pk=question_id)
+        return render(request, 'polls/results.html', {'question': question})
 
 
 This is almost exactly the same as the ``detail()`` view from :doc:`Tutorial 3
 This is almost exactly the same as the ``detail()`` view from :doc:`Tutorial 3
 </intro/tutorial03>`. The only difference is the template name. We'll fix this
 </intro/tutorial03>`. The only difference is the template name. We'll fix this
@@ -150,17 +151,17 @@ Now, create a ``polls/results.html`` template:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <h1>{{ poll.question }}</h1>
+    <h1>{{ question.question_text }}</h1>
 
 
     <ul>
     <ul>
-    {% for choice in poll.choice_set.all %}
+    {% for choice in question.choice_set.all %}
         <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
         <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
     {% endfor %}
     {% endfor %}
     </ul>
     </ul>
 
 
-    <a href="{% url 'polls:detail' poll.id %}">Vote again?</a>
+    <a href="{% url 'polls:detail' question.id %}">Vote again?</a>
 
 
-Now, go to ``/polls/1/`` in your browser and vote in the poll. You should see a
+Now, go to ``/polls/1/`` in your browser and vote in the question. You should see a
 results page that gets updated each time you vote. If you submit the form
 results page that gets updated each time you vote. If you submit the form
 without having chosen a choice, you should see the error message.
 without having chosen a choice, you should see the error message.
 
 
@@ -214,7 +215,7 @@ First, open the ``polls/urls.py`` URLconf and change it like so::
         url(r'^$', views.IndexView.as_view(), name='index'),
         url(r'^$', views.IndexView.as_view(), name='index'),
         url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
         url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
         url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'),
         url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'),
-        url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
+        url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
     )
     )
 
 
 Amend views
 Amend views
@@ -229,27 +230,29 @@ views and use Django's generic views instead. To do so, open the
     from django.core.urlresolvers import reverse
     from django.core.urlresolvers import reverse
     from django.views import generic
     from django.views import generic
 
 
-    from polls.models import Choice, Poll
+    from polls.models import Choice, Question
+
 
 
     class IndexView(generic.ListView):
     class IndexView(generic.ListView):
         template_name = 'polls/index.html'
         template_name = 'polls/index.html'
-        context_object_name = 'latest_poll_list'
+        context_object_name = 'latest_question_list'
 
 
         def get_queryset(self):
         def get_queryset(self):
-            """Return the last five published polls."""
-            return Poll.objects.order_by('-pub_date')[:5]
+            """Return the last five published questions."""
+            return Question.objects.order_by('-pub_date')[:5]
 
 
 
 
     class DetailView(generic.DetailView):
     class DetailView(generic.DetailView):
-        model = Poll
+        model = Question
         template_name = 'polls/detail.html'
         template_name = 'polls/detail.html'
 
 
 
 
     class ResultsView(generic.DetailView):
     class ResultsView(generic.DetailView):
-        model = Poll
+        model = Question
         template_name = 'polls/results.html'
         template_name = 'polls/results.html'
 
 
-    def vote(request, poll_id):
+
+    def vote(request, question_id):
         ....
         ....
 
 
 We're using two generic views here:
 We're using two generic views here:
@@ -263,12 +266,12 @@ two views abstract the concepts of "display a list of objects" and
 
 
 * The :class:`~django.views.generic.detail.DetailView` generic view
 * The :class:`~django.views.generic.detail.DetailView` generic view
   expects the primary key value captured from the URL to be called
   expects the primary key value captured from the URL to be called
-  ``"pk"``, so we've changed ``poll_id`` to ``pk`` for the generic
+  ``"pk"``, so we've changed ``question_id`` to ``pk`` for the generic
   views.
   views.
 
 
 By default, the :class:`~django.views.generic.detail.DetailView` generic
 By default, the :class:`~django.views.generic.detail.DetailView` generic
 view uses a template called ``<app name>/<model name>_detail.html``.
 view uses a template called ``<app name>/<model name>_detail.html``.
-In our case, it'll use the template ``"polls/poll_detail.html"``. The
+In our case, it'll use the template ``"polls/question_detail.html"``. The
 ``template_name`` attribute is used to tell Django to use a specific
 ``template_name`` attribute is used to tell Django to use a specific
 template name instead of the autogenerated default template name. We
 template name instead of the autogenerated default template name. We
 also specify the ``template_name`` for the ``results`` list view --
 also specify the ``template_name`` for the ``results`` list view --
@@ -283,13 +286,13 @@ name>_list.html``; we use ``template_name`` to tell
 ``"polls/index.html"`` template.
 ``"polls/index.html"`` template.
 
 
 In previous parts of the tutorial, the templates have been provided
 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
+with a context that contains the ``question`` and ``latest_question_list``
+context variables. For ``DetailView`` the ``question`` variable is provided
+automatically -- since we're using a Django model (``Question``), Django
 is able to determine an appropriate name for the context variable.
 is able to determine an appropriate name for the context variable.
 However, for ListView, the automatically generated context variable is
 However, for ListView, the automatically generated context variable is
-``poll_list``. To override this we provide the ``context_object_name``
-attribute, specifying that we want to use ``latest_poll_list`` instead.
+``question_list``. To override this we provide the ``context_object_name``
+attribute, specifying that we want to use ``latest_question_list`` instead.
 As an alternative approach, you could change your templates to match
 As an alternative approach, you could change your templates to match
 the new default context variables -- but it's a lot easier to just
 the new default context variables -- but it's a lot easier to just
 tell Django to use the variable you want.
 tell Django to use the variable you want.

+ 144 - 128
docs/intro/tutorial05.txt

@@ -130,22 +130,22 @@ We identify a bug
 -----------------
 -----------------
 
 
 Fortunately, there's a little bug in the ``polls`` application for us to fix
 Fortunately, there's a little bug in the ``polls`` application for us to fix
-right away: the ``Poll.was_published_recently()`` method returns ``True`` if
-the ``Poll`` was published within the last day (which is correct) but also if
-the ``Poll``’s ``pub_date`` field is in the future (which certainly isn't).
+right away: the ``Question.was_published_recently()`` method returns ``True`` if
+the ``Question`` was published within the last day (which is correct) but also if
+the ``Question``’s ``pub_date`` field is in the future (which certainly isn't).
 
 
-You can see this in the Admin; create a poll whose date lies in the future;
-you'll see that the ``Poll`` change list claims it was published recently.
+You can see this in the Admin; create a question whose date lies in the future;
+you'll see that the ``Question`` change list claims it was published recently.
 
 
 You can also see this using the shell::
 You can also see this using the shell::
 
 
     >>> import datetime
     >>> import datetime
     >>> from django.utils import timezone
     >>> from django.utils import timezone
-    >>> from polls.models import Poll
-    >>> # create a Poll instance with pub_date 30 days in the future
-    >>> future_poll = Poll(pub_date=timezone.now() + datetime.timedelta(days=30))
+    >>> from polls.models import Question
+    >>> # create a Question instance with pub_date 30 days in the future
+    >>> future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
     >>> # was it published recently?
     >>> # was it published recently?
-    >>> future_poll.was_published_recently()
+    >>> future_question.was_published_recently()
     True
     True
 
 
 Since things in the future are not 'recent', this is clearly wrong.
 Since things in the future are not 'recent', this is clearly wrong.
@@ -167,20 +167,21 @@ Put the following in the ``tests.py`` file in the ``polls`` application::
     from django.utils import timezone
     from django.utils import timezone
     from django.test import TestCase
     from django.test import TestCase
 
 
-    from polls.models import Poll
+    from polls.models import Question
 
 
-    class PollMethodTests(TestCase):
+    class QuestionMethodTests(TestCase):
 
 
-        def test_was_published_recently_with_future_poll(self):
+        def test_was_published_recently_with_future_question(self):
             """
             """
-            was_published_recently() should return False for polls whose
+            was_published_recently() should return False for questions whose
             pub_date is in the future
             pub_date is in the future
             """
             """
-            future_poll = Poll(pub_date=timezone.now() + datetime.timedelta(days=30))
-            self.assertEqual(future_poll.was_published_recently(), False)
+            time = timezone.now() + datetime.timedelta(days=30)
+            future_question = Question(pub_date=time)
+            self.assertEqual(future_question.was_published_recently(), False)
 
 
 What we have done here is created a :class:`django.test.TestCase` subclass
 What we have done here is created a :class:`django.test.TestCase` subclass
-with a method that creates a ``Poll`` instance with a ``pub_date`` in the
+with a method that creates a ``Question`` instance with a ``pub_date`` in the
 future. We then check the output of ``was_published_recently()`` - which
 future. We then check the output of ``was_published_recently()`` - which
 *ought* to be False.
 *ought* to be False.
 
 
@@ -196,11 +197,11 @@ and you'll see something like::
     Creating test database for alias 'default'...
     Creating test database for alias 'default'...
     F
     F
     ======================================================================
     ======================================================================
-    FAIL: test_was_published_recently_with_future_poll (polls.tests.PollMethodTests)
+    FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMethodTests)
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     Traceback (most recent call last):
     Traceback (most recent call last):
-      File "/path/to/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_poll
-        self.assertEqual(future_poll.was_published_recently(), False)
+      File "/path/to/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_question
+        self.assertEqual(future_question.was_published_recently(), False)
     AssertionError: True != False
     AssertionError: True != False
 
 
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
@@ -219,7 +220,7 @@ What happened is this:
 
 
 * it looked for test methods - ones whose names begin with ``test``
 * it looked for test methods - ones whose names begin with ``test``
 
 
-* in ``test_was_published_recently_with_future_poll`` it created a ``Poll``
+* in ``test_was_published_recently_with_future_question`` it created a ``Question``
   instance whose ``pub_date`` field is 30 days in the future
   instance whose ``pub_date`` field is 30 days in the future
 
 
 * ... and using the ``assertEqual()`` method, it discovered that its
 * ... and using the ``assertEqual()`` method, it discovered that its
@@ -232,14 +233,14 @@ occurred.
 Fixing the bug
 Fixing the bug
 --------------
 --------------
 
 
-We already know what the problem is: ``Poll.was_published_recently()`` should
+We already know what the problem is: ``Question.was_published_recently()`` should
 return ``False`` if its ``pub_date`` is in the future. Amend the method in
 return ``False`` if its ``pub_date`` is in the future. Amend the method in
 ``models.py``, so that it will only return ``True`` if the date is also in the
 ``models.py``, so that it will only return ``True`` if the date is also in the
 past::
 past::
 
 
     def was_published_recently(self):
     def was_published_recently(self):
         now = timezone.now()
         now = timezone.now()
-        return now - datetime.timedelta(days=1) <= self.pub_date <  now
+        return now - datetime.timedelta(days=1) <= self.pub_date < now
 
 
 and run the test again::
 and run the test again::
 
 
@@ -269,24 +270,26 @@ introduced another.
 Add two more test methods to the same class, to test the behavior of the method
 Add two more test methods to the same class, to test the behavior of the method
 more comprehensively::
 more comprehensively::
 
 
-    def test_was_published_recently_with_old_poll(self):
+    def test_was_published_recently_with_old_question(self):
         """
         """
-        was_published_recently() should return False for polls whose pub_date
-        is older than 1 day
+        was_published_recently() should return False for questions whose
+        pub_date is older than 1 day
         """
         """
-        old_poll = Poll(pub_date=timezone.now() - datetime.timedelta(days=30))
-        self.assertEqual(old_poll.was_published_recently(), False)
+        time = timezone.now() - datetime.timedelta(days=30)
+        old_question = Question(pub_date=time)
+        self.assertEqual(old_question.was_published_recently(), False)
 
 
-    def test_was_published_recently_with_recent_poll(self):
+    def test_was_published_recently_with_recent_question(self):
         """
         """
-        was_published_recently() should return True for polls whose pub_date
-        is within the last day
+        was_published_recently() should return True for questions whose
+        pub_date is within the last day
         """
         """
-        recent_poll = Poll(pub_date=timezone.now() - datetime.timedelta(hours=1))
-        self.assertEqual(recent_poll.was_published_recently(), True)
+        time = timezone.now() - datetime.timedelta(hours=1)
+        recent_question = Question(pub_date=time)
+        self.assertEqual(recent_question.was_published_recently(), True)
 
 
-And now we have three tests that confirm that ``Poll.was_published_recently()``
-returns sensible values for past, recent, and future polls.
+And now we have three tests that confirm that ``Question.was_published_recently()``
+returns sensible values for past, recent, and future questions.
 
 
 Again, ``polls`` is a simple application, but however complex it grows in the
 Again, ``polls`` is a simple application, but however complex it grows in the
 future and whatever other code it interacts with, we now have some guarantee
 future and whatever other code it interacts with, we now have some guarantee
@@ -295,9 +298,9 @@ that the method we have written tests for will behave in expected ways.
 Test a view
 Test a view
 ===========
 ===========
 
 
-The polls application is fairly undiscriminating: it will publish any poll,
+The polls application is fairly undiscriminating: it will publish any question,
 including ones whose ``pub_date`` field lies in the future. We should improve
 including ones whose ``pub_date`` field lies in the future. We should improve
-this. Setting a ``pub_date`` in the future should mean that the Poll is
+this. Setting a ``pub_date`` in the future should mean that the Question is
 published at that moment, but invisible until then.
 published at that moment, but invisible until then.
 
 
 A test for a view
 A test for a view
@@ -332,7 +335,7 @@ which will allow us to examine some additional attributes on responses such as
 ``response.context`` that otherwise wouldn't be available. Note that this
 ``response.context`` that otherwise wouldn't be available. Note that this
 method *does not* setup a test database, so the following will be run against
 method *does not* setup a test database, so the following will be run against
 the existing database and the output may differ slightly depending on what
 the existing database and the output may differ slightly depending on what
-polls you already created.
+questions you already created.
 
 
 Next we need to import the test client class (later in ``tests.py`` we will use
 Next we need to import the test client class (later in ``tests.py`` we will use
 the :class:`django.test.TestCase` class, which comes with its own client, so
 the :class:`django.test.TestCase` class, which comes with its own client, so
@@ -360,17 +363,17 @@ With that ready, we can ask the client to do some work for us::
     >>> # note - you might get unexpected results if your ``TIME_ZONE``
     >>> # note - you might get unexpected results if your ``TIME_ZONE``
     >>> # in ``settings.py`` is not correct. If you need to change it,
     >>> # in ``settings.py`` is not correct. If you need to change it,
     >>> # you will also need to restart your shell session
     >>> # you will also need to restart your shell session
-    >>> from polls.models import Poll
+    >>> from polls.models import Question
     >>> from django.utils import timezone
     >>> from django.utils import timezone
-    >>> # create a Poll and save it
-    >>> p = Poll(question="Who is your favorite Beatle?", pub_date=timezone.now())
-    >>> p.save()
+    >>> # create a Question and save it
+    >>> q = Question(question_text="Who is your favorite Beatle?", pub_date=timezone.now())
+    >>> q.save()
     >>> # check the response once again
     >>> # check the response once again
     >>> response = client.get('/polls/')
     >>> response = client.get('/polls/')
     >>> response.content
     >>> response.content
     '\n\n\n    <ul>\n    \n        <li><a href="/polls/1/">Who is your favorite Beatle?</a></li>\n    \n    </ul>\n\n'
     '\n\n\n    <ul>\n    \n        <li><a href="/polls/1/">Who is your favorite Beatle?</a></li>\n    \n    </ul>\n\n'
-    >>> response.context['latest_poll_list']
-    [<Poll: Who is your favorite Beatle?>]
+    >>> response.context['latest_question_list']
+    [<Question: Who is your favorite Beatle?>]
 
 
 Improving our view
 Improving our view
 ------------------
 ------------------
@@ -383,13 +386,13 @@ based on :class:`~django.views.generic.list.ListView`::
 
 
     class IndexView(generic.ListView):
     class IndexView(generic.ListView):
         template_name = 'polls/index.html'
         template_name = 'polls/index.html'
-        context_object_name = 'latest_poll_list'
+        context_object_name = 'latest_question_list'
 
 
         def get_queryset(self):
         def get_queryset(self):
-            """Return the last five published polls."""
-            return Poll.objects.order_by('-pub_date')[:5]
+            """Return the last five published questions."""
+            return Question.objects.order_by('-pub_date')[:5]
 
 
-``response.context_data['latest_poll_list']`` extracts the data this view
+``response.context_data['latest_question_list']`` extracts the data this view
 places into the context.
 places into the context.
 
 
 We need to amend the ``get_queryset`` method and change it so that it also
 We need to amend the ``get_queryset`` method and change it so that it also
@@ -402,24 +405,24 @@ and then we must amend the ``get_queryset`` method like so::
 
 
     def get_queryset(self):
     def get_queryset(self):
         """
         """
-        Return the last five published polls (not including those set to be
+        Return the last five published questions (not including those set to be
         published in the future).
         published in the future).
         """
         """
-        return Poll.objects.filter(
+        return Question.objects.filter(
             pub_date__lte=timezone.now()
             pub_date__lte=timezone.now()
         ).order_by('-pub_date')[:5]
         ).order_by('-pub_date')[:5]
 
 
-``Poll.objects.filter(pub_date__lte=timezone.now())`` returns a queryset
-containing Polls whose ``pub_date`` is less than or equal to - that is, earlier
-than or equal to - ``timezone.now``.
+``Question.objects.filter(pub_date__lte=timezone.now())`` returns a queryset
+containing ``Question``\s whose ``pub_date`` is less than or equal to - that
+is, earlier than or equal to - ``timezone.now``.
 
 
 Testing our new view
 Testing our new view
 --------------------
 --------------------
 
 
 Now you can satisfy yourself that this behaves as expected by firing up the
 Now you can satisfy yourself that this behaves as expected by firing up the
-runserver, loading the site in your browser, creating ``Polls`` with dates in
-the past and future, and checking that only those that have been published are
-listed.  You don't want to have to do that *every single time you make any
+runserver, loading the site in your browser, creating ``Questions`` with dates
+in the past and future, and checking that only those that have been published
+are listed.  You don't want to have to do that *every single time you make any
 change that might affect this* - so let's also create a test, based on our
 change that might affect this* - so let's also create a test, based on our
 shell session above.
 shell session above.
 
 
@@ -427,91 +430,98 @@ Add the following to ``polls/tests.py``::
 
 
     from django.core.urlresolvers import reverse
     from django.core.urlresolvers import reverse
 
 
-and we'll create a factory method to create polls as well as a new test class::
+and we'll create a factory method to create questions as well as a new test
+class::
 
 
-    def create_poll(question, days):
+    def create_question(question_text, days):
         """
         """
-        Creates a poll with the given `question` published the given number of
-        `days` offset to now (negative for polls published in the past,
-        positive for polls that have yet to be published).
+        Creates a question with the given `question_text` published the given
+        number of `days` offset to now (negative for questions published
+        in the past, positive for questions that have yet to be published).
         """
         """
-        return Poll.objects.create(question=question,
-            pub_date=timezone.now() + datetime.timedelta(days=days))
+        time = timezone.now() + datetime.timedelta(days=days)
+        return Question.objects.create(question_text=question_text,
+                                       pub_date=time)
 
 
-    class PollViewTests(TestCase):
-        def test_index_view_with_no_polls(self):
+
+    class QuestionViewTests(TestCase):
+        def test_index_view_with_no_questions(self):
             """
             """
-            If no polls exist, an appropriate message should be displayed.
+            If no questions exist, an appropriate message should be displayed.
             """
             """
             response = self.client.get(reverse('polls:index'))
             response = self.client.get(reverse('polls:index'))
             self.assertEqual(response.status_code, 200)
             self.assertEqual(response.status_code, 200)
             self.assertContains(response, "No polls are available.")
             self.assertContains(response, "No polls are available.")
-            self.assertQuerysetEqual(response.context['latest_poll_list'], [])
+            self.assertQuerysetEqual(response.context['latest_question_list'], [])
 
 
-        def test_index_view_with_a_past_poll(self):
+        def test_index_view_with_a_past_question(self):
             """
             """
-            Polls with a pub_date in the past should be displayed on the index page.
+            Questions with a pub_date in the past should be displayed on the
+            index page
             """
             """
-            create_poll(question="Past poll.", days=-30)
+            create_question(question_text="Past question.", days=-30)
             response = self.client.get(reverse('polls:index'))
             response = self.client.get(reverse('polls:index'))
             self.assertQuerysetEqual(
             self.assertQuerysetEqual(
-                response.context['latest_poll_list'],
-                ['<Poll: Past poll.>']
+                response.context['latest_question_list'],
+                ['<Question: Past question.>']
             )
             )
 
 
-        def test_index_view_with_a_future_poll(self):
+        def test_index_view_with_a_future_question(self):
             """
             """
-            Polls with a pub_date in the future should not be displayed on the
-            index page.
+            Questions with a pub_date in the future should not be displayed on
+            the index page.
             """
             """
-            create_poll(question="Future poll.", days=30)
+            create_question(question_text="Future question.", days=30)
             response = self.client.get(reverse('polls:index'))
             response = self.client.get(reverse('polls:index'))
-            self.assertContains(response, "No polls are available.", status_code=200)
-            self.assertQuerysetEqual(response.context['latest_poll_list'], [])
+            self.assertContains(response, "No polls are available.",
+                                status_code=200)
+            self.assertQuerysetEqual(response.context['latest_question_list'], [])
 
 
-        def test_index_view_with_future_poll_and_past_poll(self):
+        def test_index_view_with_future_question_and_past_question(self):
             """
             """
-            Even if both past and future polls exist, only past polls should be
-            displayed.
+            Even if both past and future questions exist, only past questions
+            should be displayed.
             """
             """
-            create_poll(question="Past poll.", days=-30)
-            create_poll(question="Future poll.", days=30)
+            create_question(question_text="Past question.", days=-30)
+            create_question(question_text="Future question.", days=30)
             response = self.client.get(reverse('polls:index'))
             response = self.client.get(reverse('polls:index'))
             self.assertQuerysetEqual(
             self.assertQuerysetEqual(
-                response.context['latest_poll_list'],
-                ['<Poll: Past poll.>']
+                response.context['latest_question_list'],
+                ['<Question: Past question.>']
             )
             )
 
 
-        def test_index_view_with_two_past_polls(self):
+        def test_index_view_with_two_past_questions(self):
             """
             """
-            The polls index page may display multiple polls.
+            The questions index page may display multiple questions.
             """
             """
-            create_poll(question="Past poll 1.", days=-30)
-            create_poll(question="Past poll 2.", days=-5)
+            create_question(question_text="Past quesiton 1.", days=-30)
+            create_question(question_text="Past question 2.", days=-5)
             response = self.client.get(reverse('polls:index'))
             response = self.client.get(reverse('polls:index'))
             self.assertQuerysetEqual(
             self.assertQuerysetEqual(
-                response.context['latest_poll_list'],
-                 ['<Poll: Past poll 2.>', '<Poll: Past poll 1.>']
+                response.context['latest_question_list'],
+                ['<Question: Past question 2.>', '<Question: Past question 1.>']
             )
             )
 
 
+
 Let's look at some of these more closely.
 Let's look at some of these more closely.
 
 
-First is a poll factory method, ``create_poll``, to take some repetition out
-of the process of creating polls.
+First is a question factory method, ``create_question``, to take some
+repetition out of the process of creating questions.
 
 
-``test_index_view_with_no_polls`` doesn't create any polls, but checks the
-message: "No polls are available." and verifies the ``latest_poll_list`` is
-empty. Note that the :class:`django.test.TestCase` class provides some
+``test_index_view_with_no_questions`` doesn't create any questions, but checks
+the message: "No polls are available." and verifies the ``latest_question_list``
+is empty. Note that the :class:`django.test.TestCase` class provides some
 additional assertion methods. In these examples, we use
 additional assertion methods. In these examples, we use
 :meth:`~django.test.SimpleTestCase.assertContains()` and
 :meth:`~django.test.SimpleTestCase.assertContains()` and
 :meth:`~django.test.TransactionTestCase.assertQuerysetEqual()`.
 :meth:`~django.test.TransactionTestCase.assertQuerysetEqual()`.
 
 
-In ``test_index_view_with_a_past_poll``, we create a poll and verify that it
+In ``test_index_view_with_a_past_question``, we create a question and verify that it
 appears in the list.
 appears in the list.
 
 
-In ``test_index_view_with_a_future_poll``, we create a poll with a ``pub_date``
-in the future. The database is reset for each test method, so the first poll is
-no longer there, and so again the index shouldn't have any polls in it.
+In ``test_index_view_with_a_future_question``, we create a question with a
+``pub_date`` in the future. The database is reset for each test method, so the
+first question is no longer there, and so again the index shouldn't have any
+questions in it.
 
 
 And so on. In effect, we are using the tests to tell a story of admin input
 And so on. In effect, we are using the tests to tell a story of admin input
 and user experience on the site, and checking that at every state and for every
 and user experience on the site, and checking that at every state and for every
@@ -520,41 +530,47 @@ new change in the state of the system, the expected results are published.
 Testing the ``DetailView``
 Testing the ``DetailView``
 --------------------------
 --------------------------
 
 
-What we have works well; however, even though future polls don't appear in the
-*index*, users can still reach them if they know or guess the right URL. So we
-need to add a similar  constraint to ``DetailView``::
+What we have works well; however, even though future questions don't appear in
+the *index*, users can still reach them if they know or guess the right URL. So
+we need to add a similar  constraint to ``DetailView``::
 
 
 
 
     class DetailView(generic.DetailView):
     class DetailView(generic.DetailView):
         ...
         ...
         def get_queryset(self):
         def get_queryset(self):
             """
             """
-            Excludes any polls that aren't published yet.
+            Excludes any questions that aren't published yet.
             """
             """
-            return Poll.objects.filter(pub_date__lte=timezone.now())
+            return Question.objects.filter(pub_date__lte=timezone.now())
 
 
-And of course, we will add some tests, to check that a ``Poll`` whose
+And of course, we will add some tests, to check that a ``Question`` whose
 ``pub_date`` is in the past can be displayed, and that one with a ``pub_date``
 ``pub_date`` is in the past can be displayed, and that one with a ``pub_date``
 in the future is not::
 in the future is not::
 
 
-    class PollIndexDetailTests(TestCase):
-        def test_detail_view_with_a_future_poll(self):
+    class QuestionIndexDetailTests(TestCase):
+        def test_detail_view_with_a_future_question(self):
             """
             """
-            The detail view of a poll with a pub_date in the future should
+            The detail view of a question with a pub_date in the future should
             return a 404 not found.
             return a 404 not found.
             """
             """
-            future_poll = create_poll(question='Future poll.', days=5)
-            response = self.client.get(reverse('polls:detail', args=(future_poll.id,)))
+            future_question = create_question(question_text='Future question.',
+                                              days=5)
+            response = self.client.get(reverse('polls:detail',
+                                       args=(future_question.id,)))
             self.assertEqual(response.status_code, 404)
             self.assertEqual(response.status_code, 404)
 
 
-        def test_detail_view_with_a_past_poll(self):
+        def test_detail_view_with_a_past_question(self):
             """
             """
-            The detail view of a poll with a pub_date in the past should display
-            the poll's question.
+            The detail view of a question with a pub_date in the past should
+            display the question's text.
             """
             """
-            past_poll = create_poll(question='Past Poll.', days=-5)
-            response = self.client.get(reverse('polls:detail', args=(past_poll.id,)))
-            self.assertContains(response, past_poll.question, status_code=200)
+            past_question = create_question(question_text='Past Question.',
+                                            days=-5)
+            response = self.client.get(reverse('polls:detail',
+                                       args=(past_question.id,)))
+            self.assertContains(response, past_question.question_text,
+                                status_code=200)
+
 
 
 Ideas for more tests
 Ideas for more tests
 --------------------
 --------------------
@@ -564,17 +580,17 @@ create a new test class for that view. It'll be very similar to what we have
 just created; in fact there will be a lot of repetition.
 just created; in fact there will be a lot of repetition.
 
 
 We could also improve our application in other ways, adding tests along the
 We could also improve our application in other ways, adding tests along the
-way. For example, it's silly that ``Polls`` can be published on the site that
-have no ``Choices``. So, our views could check for this, and exclude such
-``Polls``. Our tests would create a ``Poll`` without ``Choices`` and then test
-that it's not published, as well as create a similar ``Poll`` *with*
-``Choices``, and test that it *is* published.
-
-Perhaps logged-in admin users should be allowed to see unpublished ``Polls``,
-but not ordinary visitors. Again: whatever needs to be added to the software to
-accomplish this should be accompanied by a test, whether you write the test
-first and then make the code pass the test, or work out the logic in your code
-first and then write a test to prove it.
+way. For example, it's silly that ``Questions`` can be published on the site
+that have no ``Choices``. So, our views could check for this, and exclude such
+``Questions``. Our tests would create a ``Question`` without ``Choices`` and
+then test that it's not published, as well as create a similar ``Question``
+*with* ``Choices``, and test that it *is* published.
+
+Perhaps logged-in admin users should be allowed to see unpublished
+``Questions``, but not ordinary visitors. Again: whatever needs to be added to
+the software to accomplish this should be accompanied by a test, whether you
+write the test first and then make the code pass the test, or work out the
+logic in your code first and then write a test to prove it.
 
 
 At a certain point you are bound to look at your tests and wonder whether your
 At a certain point you are bound to look at your tests and wonder whether your
 code is suffering from test bloat, which brings us to:
 code is suffering from test bloat, which brings us to:
@@ -591,7 +607,7 @@ once and then forget about it. It will continue performing its useful function
 as you continue to develop your program.
 as you continue to develop your program.
 
 
 Sometimes tests will need to be updated. Suppose that we amend our views so that
 Sometimes tests will need to be updated. Suppose that we amend our views so that
-only ``Polls`` with ``Choices`` are published. In that case, many of our
+only ``Questions`` with ``Choices`` are published. In that case, many of our
 existing tests will fail - *telling us exactly which tests need to be amended to
 existing tests will fail - *telling us exactly which tests need to be amended to
 bring them up to date*, so to that extent tests help look after themselves.
 bring them up to date*, so to that extent tests help look after themselves.
 
 

+ 1 - 1
docs/intro/tutorial06.txt

@@ -75,7 +75,7 @@ template tag from the ``staticfiles`` template library. The ``{% static %}``
 template tag generates the absolute URL of the static file.
 template tag generates the absolute URL of the static file.
 
 
 That's all you need to do for development. Reload
 That's all you need to do for development. Reload
-``http://localhost:8000/polls/`` and you should see that the poll links are
+``http://localhost:8000/polls/`` and you should see that the question links are
 green (Django style!) which means that your stylesheet was properly loaded.
 green (Django style!) which means that your stylesheet was properly loaded.
 
 
 Adding a background-image
 Adding a background-image