From 824ca0d6e560684bd0c09b09afece2586176a2c7 Mon Sep 17 00:00:00 2001 From: Simon Meers Date: Sat, 9 Oct 2010 07:48:09 +0000 Subject: [PATCH] [1.2.X] Fixed #14255 -- factor project name out of app imports in tutorial. Thanks to adamend for the report and initial patch. Backport of r14066 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@14067 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/intro/tutorial01.txt | 26 ++++++++++----------- docs/intro/tutorial02.txt | 4 ++-- docs/intro/tutorial03.txt | 48 +++++++++++++++++++-------------------- docs/intro/tutorial04.txt | 12 +++++----- 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index 6045eb111e695..be98742469bad 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -268,10 +268,8 @@ so you can focus on writing code rather than creating directories. configuration and apps for a particular Web site. A project can contain multiple apps. An app can be in multiple projects. -In this tutorial, we'll create our poll app in the :file:`mysite` directory, -for simplicity. As a consequence, the app will be coupled to the project -- -that is, Python code within the poll app will refer to ``mysite.polls``. -Later in this tutorial, we'll discuss decoupling your apps for distribution. +Your apps can live anywhere on your `Python path`_. In this tutorial we will +create our poll app in the :file:`mysite` directory for simplicity. To create your app, make sure you're in the :file:`mysite` directory and type this command: @@ -369,7 +367,7 @@ But first we need to tell our project that the ``polls`` app is installed. Django installation. Edit the :file:`settings.py` file again, and change the -:setting:`INSTALLED_APPS` setting to include the string ``'mysite.polls'``. So +:setting:`INSTALLED_APPS` setting to include the string ``'polls'``. So it'll look like this:: INSTALLED_APPS = ( @@ -377,10 +375,10 @@ it'll look like this:: 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', - 'mysite.polls' + 'polls' ) -Now Django knows ``mysite`` includes the ``polls`` app. Let's run another +Now Django knows to include the ``polls`` app. Let's run another command: .. code-block:: bash @@ -488,9 +486,9 @@ We're using this instead of simply typing "python", because ``manage.py`` sets up the project's environment for you. "Setting up the environment" involves two things: - * Putting ``mysite`` on ``sys.path``. For flexibility, several pieces of + * Putting ``polls`` on ``sys.path``. For flexibility, several pieces of Django refer to projects in Python dotted-path notation (e.g. - ``'mysite.polls.models'``). In order for this to work, the ``mysite`` + ``'polls.models'``). In order for this to work, the ``polls`` package has to be on ``sys.path``. We've already seen one example of this: the :setting:`INSTALLED_APPS` @@ -502,16 +500,16 @@ things: .. admonition:: Bypassing manage.py If you'd rather not use ``manage.py``, no problem. Just make sure ``mysite`` - is at the root level on the Python path (i.e., ``import mysite`` works) and - set the ``DJANGO_SETTINGS_MODULE`` environment variable to - ``mysite.settings``. + and ``polls`` are at the root level on the Python path (i.e., ``import mysite`` + and ``import polls`` work) and set the ``DJANGO_SETTINGS_MODULE`` environment + variable to ``mysite.settings``. For more information on all of this, see the :doc:`django-admin.py documentation `. Once you're in the shell, explore the :doc:`database API `:: - >>> from mysite.polls.models import Poll, Choice # Import the model classes we just wrote. + >>> from polls.models import Poll, Choice # Import the model classes we just wrote. # No polls are in the system yet. >>> Poll.objects.all() @@ -619,7 +617,7 @@ Note the addition of ``import datetime`` to reference Python's standard Save these changes and start a new Python interactive shell by running ``python manage.py shell`` again:: - >>> from mysite.polls.models import Poll, Choice + >>> from polls.models import Poll, Choice # Make sure our __unicode__() addition worked. >>> Poll.objects.all() diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index d43df9ed53c2c..c80d87d835781 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -103,7 +103,7 @@ Just one thing to do: We need to tell the admin that ``Poll`` objects have an admin interface. To do this, create a file called ``admin.py`` in your ``polls`` directory, and edit it to look like this:: - from mysite.polls.models import Poll + from polls.models import Poll from django.contrib import admin admin.site.register(Poll) @@ -239,7 +239,7 @@ Yet. 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:: - from mysite.polls.models import Choice + from polls.models import Choice admin.site.register(Choice) diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt index d3470359aaf82..6da0ad4029b74 100644 --- a/docs/intro/tutorial03.txt +++ b/docs/intro/tutorial03.txt @@ -84,10 +84,10 @@ Time for an example. Edit ``mysite/urls.py`` so it looks like this:: admin.autodiscover() urlpatterns = patterns('', - (r'^polls/$', 'mysite.polls.views.index'), - (r'^polls/(?P\d+)/$', 'mysite.polls.views.detail'), - (r'^polls/(?P\d+)/results/$', 'mysite.polls.views.results'), - (r'^polls/(?P\d+)/vote/$', 'mysite.polls.views.vote'), + (r'^polls/$', 'polls.views.index'), + (r'^polls/(?P\d+)/$', 'polls.views.detail'), + (r'^polls/(?P\d+)/results/$', 'polls.views.results'), + (r'^polls/(?P\d+)/vote/$', 'polls.views.vote'), (r'^admin/', include(admin.site.urls)), ) @@ -96,8 +96,8 @@ This is worth a review. When somebody requests a page from your Web site -- say, the :setting:`ROOT_URLCONF` setting. It finds the variable named ``urlpatterns`` and traverses the regular expressions in order. When it finds a regular expression that matches -- ``r'^polls/(?P\d+)/$'`` -- it loads the -function ``detail()`` from ``mysite/polls/views.py``. Finally, -it calls that ``detail()`` function like so:: +function ``detail()`` from ``polls/views.py``. Finally, it calls that +``detail()`` function like so:: detail(request=, poll_id='23') @@ -112,7 +112,7 @@ what you can do with them. And there's no need to add URL cruft such as ``.php`` -- unless you have a sick sense of humor, in which case you can do something like this:: - (r'^polls/latest\.php$', 'mysite.polls.views.index'), + (r'^polls/latest\.php$', 'polls.views.index'), But, don't do that. It's silly. @@ -148,17 +148,17 @@ You should get a pleasantly-colored error page with the following message:: ViewDoesNotExist at /polls/ - Tried index in module mysite.polls.views. Error was: 'module' + Tried index in module polls.views. Error was: 'module' object has no attribute 'index' This error happened because you haven't written a function ``index()`` in the -module ``mysite/polls/views.py``. +module ``polls/views.py``. Try "/polls/23/", "/polls/23/results/" and "/polls/23/vote/". The error messages tell you which view Django tried (and failed to find, because you haven't written any views yet). -Time to write the first view. Open the file ``mysite/polls/views.py`` +Time to write the first view. Open the file ``polls/views.py`` and put the following Python code in it:: from django.http import HttpResponse @@ -207,7 +207,7 @@ in :doc:`Tutorial 1 `. Here's one stab at the ``index()`` view, which displays the latest 5 poll questions in the system, separated by commas, according to publication date:: - from mysite.polls.models import Poll + from polls.models import Poll from django.http import HttpResponse def index(request): @@ -220,7 +220,7 @@ you want to change the way the page looks, you'll have to edit this Python code. So let's use Django's template system to separate the design from Python:: from django.template import Context, loader - from mysite.polls.models import Poll + from polls.models import Poll from django.http import HttpResponse def index(request): @@ -279,7 +279,7 @@ template. Django provides a shortcut. Here's the full ``index()`` view, rewritten:: from django.shortcuts import render_to_response - from mysite.polls.models import Poll + from polls.models import Poll def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] @@ -432,19 +432,19 @@ Take some time to play around with the views and template system. As you edit the URLconf, you may notice there's a fair bit of redundancy in it:: urlpatterns = patterns('', - (r'^polls/$', 'mysite.polls.views.index'), - (r'^polls/(?P\d+)/$', 'mysite.polls.views.detail'), - (r'^polls/(?P\d+)/results/$', 'mysite.polls.views.results'), - (r'^polls/(?P\d+)/vote/$', 'mysite.polls.views.vote'), + (r'^polls/$', 'polls.views.index'), + (r'^polls/(?P\d+)/$', 'polls.views.detail'), + (r'^polls/(?P\d+)/results/$', 'polls.views.results'), + (r'^polls/(?P\d+)/vote/$', 'polls.views.vote'), ) -Namely, ``mysite.polls.views`` is in every callback. +Namely, ``polls.views`` is in every callback. Because this is a common case, the URLconf framework provides a shortcut for common prefixes. You can factor out the common prefixes and add them as the first argument to :func:`~django.conf.urls.defaults.patterns`, like so:: - urlpatterns = patterns('mysite.polls.views', + urlpatterns = patterns('polls.views', (r'^polls/$', 'index'), (r'^polls/(?P\d+)/$', 'detail'), (r'^polls/(?P\d+)/results/$', 'results'), @@ -470,7 +470,7 @@ We've been editing the URLs in ``mysite/urls.py``, but the URL design of an app is specific to the app, not to the Django installation -- so let's move the URLs within the app directory. -Copy the file ``mysite/urls.py`` to ``mysite/polls/urls.py``. Then, change +Copy the file ``mysite/urls.py`` to ``polls/urls.py``. Then, change ``mysite/urls.py`` to remove the poll-specific URLs and insert an :func:`~django.conf.urls.defaults.include`:: @@ -479,7 +479,7 @@ Copy the file ``mysite/urls.py`` to ``mysite/polls/urls.py``. Then, change # ... urlpatterns = patterns('', - (r'^polls/', include('mysite.polls.urls')), + (r'^polls/', include('polls.urls')), # ... ) @@ -495,14 +495,14 @@ Here's what happens if a user goes to "/polls/34/" in this system: * Django will find the match at ``'^polls/'`` * Then, Django will strip off the matching text (``"polls/"``) and send the - remaining text -- ``"34/"`` -- to the 'mysite.polls.urls' URLconf for + remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for further processing. -Now that we've decoupled that, we need to decouple the 'mysite.polls.urls' +Now that we've decoupled that, we need to decouple the 'polls.urls' URLconf by removing the leading "polls/" from each line, and removing the lines registering the admin site:: - urlpatterns = patterns('mysite.polls.views', + urlpatterns = patterns('polls.views', (r'^$', 'index'), (r'^(?P\d+)/$', 'detail'), (r'^(?P\d+)/results/$', 'results'), diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt index a7a9aaea3355b..dfbd82df55485 100644 --- a/docs/intro/tutorial04.txt +++ b/docs/intro/tutorial04.txt @@ -74,13 +74,13 @@ created a URLconf for the polls application that includes this line:: (r'^(?P\d+)/vote/$', 'vote'), We also created a dummy implementation of the ``vote()`` function. Let's -create a real version. Add the following to ``mysite/polls/views.py``:: +create a real version. Add the following to ``polls/views.py``:: from django.shortcuts import get_object_or_404, render_to_response from django.http import HttpResponseRedirect, HttpResponse from django.core.urlresolvers import reverse from django.template import RequestContext - from mysite.polls.models import Choice, Poll + from polls.models import Choice, Poll # ... def vote(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) @@ -98,7 +98,7 @@ create a real version. Add the following to ``mysite/polls/views.py``:: # Always return an HttpResponseRedirect after successfully dealing # with POST data. This prevents data from being posted twice if a # user hits the Back button. - return HttpResponseRedirect(reverse('mysite.polls.views.results', args=(p.id,))) + return HttpResponseRedirect(reverse('polls.views.results', args=(p.id,))) This code includes a few things we haven't covered yet in this tutorial: @@ -222,7 +222,7 @@ tutorial so far:: from django.conf.urls.defaults import * - urlpatterns = patterns('mysite.polls.views', + urlpatterns = patterns('polls.views', (r'^$', 'index'), (r'^(?P\d+)/$', 'detail'), (r'^(?P\d+)/results/$', 'results'), @@ -232,7 +232,7 @@ tutorial so far:: Change it like so:: from django.conf.urls.defaults import * - from mysite.polls.models import Poll + from polls.models import Poll info_dict = { 'queryset': Poll.objects.all(), @@ -242,7 +242,7 @@ Change it like so:: (r'^$', 'django.views.generic.list_detail.object_list', info_dict), (r'^(?P\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict), url(r'^(?P\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'), - (r'^(?P\d+)/vote/$', 'mysite.polls.views.vote'), + (r'^(?P\d+)/vote/$', 'polls.views.vote'), ) We're using two generic views here: