diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt index 99fb62e4d7..dcccd583c0 100644 --- a/docs/intro/reusable-apps.txt +++ b/docs/intro/reusable-apps.txt @@ -50,8 +50,8 @@ projects and ready to publish for others to install and use. Python package easy for others to install. It can be a little confusing, we know. -Completing your reusable app -============================ +Your project and your reusable app +================================== After the previous tutorials, our project should look like this:: @@ -67,78 +67,28 @@ After the previous tutorials, our project should look like this:: admin.py models.py tests.py - urls.py - views.py - -You also have a directory somewhere called ``mytemplates`` which you created in -:doc:`Tutorial 2 `. You specified its location in the -TEMPLATE_DIRS setting. This directory should look like this:: - - mytemplates/ - admin/ - base_site.html - polls/ - detail.html - index.html - results.html - -The polls app is already a Python package, thanks to the ``polls/__init__.py`` -file. That's a great start, but we can't just pick up this package and drop it -into a new project. The polls templates are currently stored in the -project-wide ``mytemplates`` directory. To make the app self-contained, it -should also contain the necessary templates. - -Inside the ``polls`` app, create a new ``templates`` directory. Now move the -``polls`` template directory from ``mytemplates`` into the new -``templates``. Your project should now look like this:: - - mysite/ - manage.py - mysite/ - __init__.py - settings.py - urls.py - wsgi.py - polls/ - admin.py - __init__.py - models.py templates/ polls/ detail.html index.html results.html - tests.py urls.py views.py + mytemplates/ + admin/ + base_site.html -Your project-wide templates directory should now look like this:: - - mytemplates/ - admin/ - base_site.html - -Looking good! Now would be a good time to confirm that your polls application -still works correctly. How does Django know how to find the new location of -the polls templates even though we didn't modify :setting:`TEMPLATE_DIRS`? -Django has a :setting:`TEMPLATE_LOADERS` setting which contains a list -of callables that know how to import templates from various sources. One of -the defaults is :class:`django.template.loaders.app_directories.Loader` which -looks for a "templates" subdirectory in each of the :setting:`INSTALLED_APPS`. +You created ``mysite/mytemplates`` in :doc:`Tutorial 2 `, +and ``polls/templates`` in :doc:`Tutorial 3 `. Now perhaps +it is clearer why we chose to have separate template directories for the +project and application: everything that is part of the polls application is in +``polls``. It makes the application self-contained and easier to drop into a +new project. The ``polls`` directory could now be copied into a new Django project and immediately reused. It's not quite ready to be published though. For that, we need to package the app to make it easy for others to install. -.. admonition:: Why nested? - - Why create a ``polls`` directory under ``templates`` when we're - already inside the polls app? This directory is needed to avoid conflicts in - Django's ``app_directories`` template loader. For example, if two - apps had a template called ``base.html``, without the extra directory it - wouldn't be possible to distinguish between the two. It's a good convention - to use the name of your app for this directory. - .. _installing-reusable-apps-prerequisites: Installing some prerequisites diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index 56a068ff1f..9b0c820380 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -146,7 +146,7 @@ purely in Python. We've included this with Django so you can develop things rapidly, without having to deal with configuring a production server -- such as Apache -- until you're ready for production. -Now's a good time to note: DON'T use this server in anything resembling a +Now's a good time to note: **Don't** use this server in anything resembling a production environment. It's intended only for use while developing. (We're in the business of making Web frameworks, not Web servers.) @@ -354,7 +354,7 @@ These concepts are represented by simple Python classes. Edit the class Choice(models.Model): poll = models.ForeignKey(Poll) choice_text = models.CharField(max_length=200) - votes = models.IntegerField() + votes = models.IntegerField(default=0) The code is straightforward. Each model is represented by a class that subclasses :class:`django.db.models.Model`. Each model has a number of class @@ -377,11 +377,15 @@ example, we've only defined a human-readable name for ``Poll.pub_date``. For all other fields in this model, the field's machine-readable name will suffice as its human-readable name. -Some :class:`~django.db.models.Field` classes have required elements. +Some :class:`~django.db.models.Field` classes have required arguments. :class:`~django.db.models.CharField`, for example, requires that you give it a :attr:`~django.db.models.CharField.max_length`. That's used not only in the database schema, but in validation, as we'll soon see. +A :class:`~django.db.models.Field` can also have various optional arguments; in +this case, we've set the :attr:`~django.db.models.Field.default` value of +``votes`` to 0. + Finally, note a relationship is defined, using :class:`~django.db.models.ForeignKey`. That tells Django each ``Choice`` is related to a single ``Poll``. Django supports all the common database relationships: diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index e5350a4d4c..966921f8a5 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -399,6 +399,11 @@ That's easy to change, though, using Django's template system. The Django admin is powered by Django itself, and its interfaces use Django's own template system. +.. _ref-customizing-your-projects-templates: + +Customizing your *project's* templates +-------------------------------------- + Create a ``mytemplates`` directory in your project directory. Templates can live anywhere on your filesystem that Django can access. (Django runs as whatever user your server runs.) However, keeping your templates within the @@ -446,11 +451,24 @@ override a template, just do the same thing you did with ``base_site.html`` -- copy it from the default directory into your custom directory, and make changes. +Customizing your *application's* templates +------------------------------------------ + Astute readers will ask: But if :setting:`TEMPLATE_DIRS` was empty by default, how was Django finding the default admin templates? The answer is that, by default, Django automatically looks for a ``templates/`` subdirectory within -each app package, for use as a fallback. See the :ref:`template loader -documentation ` for full information. +each application package, for use as a fallback (don't forget that +``django.contrib.admin`` is an application). + +Our poll application is not very complex and doesn't need custom admin +templates. But if it grew more sophisticated and required modification of +Django's standard admin templates for some of its functionality, it would be +more sensible to modify the *application's* templates, rather than those in the +*project*. That way, you could include the polls application in any new project +and be assured that it would find the custom templates it needed. + +See the :ref:`template loader documentation ` for more +information about how Django finds its templates. Customize the admin index page ============================== diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt index ac77b7608d..abc61a23ba 100644 --- a/docs/intro/tutorial03.txt +++ b/docs/intro/tutorial03.txt @@ -39,7 +39,24 @@ In our poll application, we'll have the following four views: * Vote action -- handles voting for a particular choice in a particular poll. -In Django, each view is represented by a simple Python function. +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 +views). Django will choose a view by examining the URL that's requested (to be +precise, the part of the URL after the domain name). + +Now in your time on the web you may have come across such beauties as +"ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B". +You will be pleased to know that Django allows us much more elegant +*URL patterns* than that. + +A URL pattern is simply the general form of a URL - for example: +``/newsarchive///``. + +To get from a URL to a view, Django uses what are known as 'URLconfs'. A +URLconf maps URL patterns (described as regular expressions) to views. + +This tutorial provides basic instruction in the use of URLconfs, and you can +refer to :mod:`django.core.urlresolvers` for more information. Write your first view ===================== @@ -52,19 +69,8 @@ and put the following Python code in it:: def index(request): return HttpResponse("Hello, world. You're at the poll index.") -This is the simplest view possible in Django. Now we have a problem, how does -this view get called? For that we need to map it to a URL, in Django this is -done in a configuration file called a URLconf. - -.. admonition:: What is a URLconf? - - In Django, web pages and other content are delivered by views and - determining which view is called is done by Python modules informally - titled 'URLconfs'. These modules are pure Python code and are a simple - mapping between URL patterns (as simple regular expressions) to Python - callback functions (your views). This tutorial provides basic instruction - in their use, and you can refer to :mod:`django.core.urlresolvers` for - more information. +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. To create a URLconf in the polls directory, create a file called ``urls.py``. Your app directory should now look like:: @@ -274,10 +280,48 @@ commas, according to publication date:: There's a problem here, though: the page's design is hard-coded in the view. If 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. +So let's use Django's template system to separate the design from Python by +creating a template that the view can use. + +First, create a directory called ``templates`` in your ``polls`` directory. +Django will look for templates in there. + +Django's :setting:`TEMPLATE_LOADERS` setting contains a list of callables that +know how to import templates from various sources. One of the defaults is +:class:`django.template.loaders.app_directories.Loader` which looks for a +"templates" subdirectory in each of the :setting:`INSTALLED_APPS` - this is how +Django knows to find the polls templates even though we didn't modify +:setting:`TEMPLATE_DIRS`, as we did in :ref:`Tutorial 2 +`. + +.. admonition:: Organizing templates + + We *could* have all our templates together, in one big templates directory, + and it would work perfectly well. However, this template belongs to the + polls application, so unlike the admin template we created in the previous + tutorial, we'll put this one in the application's template directory + (``polls/templates``) rather than the project's (``mytemplates``). We'll + discuss in more detail in the :doc:`reusable apps tutorial + ` *why* we do this. + +Within the ``templates`` directory you have just created, create another +directory called ``polls``, and within that create a file called +``index.html``. In other words, your template should be at +``polls/templates/polls/index.html``. Because of how the ``app_directories`` +template loader works as described above, you can refer to this template within +Django simply as ``polls/index.html``. + +.. admonition:: Template namespacing + + Now we *might* be able to get away with putting our templates directly in + ``polls/templates`` (rather than creating another ``polls`` subdirectory), + but it would actually be a bad idea. Django will choose the first template + it finds whose name matches, and if you had a template with the same name + in a *different* application, Django would be unable to distinguish between + them. We need to be able to point Django at the right one, and the easiest + way to ensure this is by *namespacing* them. That is, by putting those + templates inside *another* directory named for the application itself. -First, create a directory ``polls`` in your template directory you specified -in :setting:`TEMPLATE_DIRS`. Within that, create a file called ``index.html``. Put the following code in that template: .. code-block:: html+django @@ -311,15 +355,9 @@ That code loads the template called ``polls/index.html`` and passes it a context. The context is a dictionary mapping template variable names to Python objects. -Load the page in your Web browser, 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. - -.. admonition:: Organizing Templates - - Rather than one big templates directory, you can also store templates - within each app. We'll discuss this in more detail in the :doc:`reusable - apps tutorial`. +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. A shortcut: :func:`~django.shortcuts.render` -------------------------------------------- @@ -536,8 +574,9 @@ view, and so might an app on the same project that is for a blog. How does one make it so that Django knows which app view to create for a url when using the ``{% url %}`` template tag? -The answer is to add namespaces to your root URLconf. In the -``mysite/urls.py`` file, go ahead and change it to include namespacing:: +The answer is to add namespaces to your root URLconf. In the ``mysite/urls.py`` +file (the project's ``urls.py``, not the application's), go ahead and change +it to include namespacing:: from django.conf.urls import patterns, include, url diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt index f047067aa7..87d8e584ad 100644 --- a/docs/intro/tutorial04.txt +++ b/docs/intro/tutorial04.txt @@ -33,7 +33,7 @@ A quick rundown: ``value`` of each radio button is the associated poll choice's ID. The ``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 - POST data ``choice=3``. This is HTML Forms 101. + 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 set ``method="post"``. Using ``method="post"`` (as opposed to @@ -199,6 +199,9 @@ Read on for details. You should know basic math before you start using a calculator. +Amend URLconf +------------- + First, open the ``polls/urls.py`` URLconf and change it like so:: from django.conf.urls import patterns, url @@ -225,6 +228,9 @@ First, open the ``polls/urls.py`` URLconf and change it like so:: url(r'^(?P\d+)/vote/$', 'polls.views.vote', name='vote'), ) +Amend views +----------- + We're using two generic views here: :class:`~django.views.generic.list.ListView` and :class:`~django.views.generic.detail.DetailView`. Respectively, those @@ -267,9 +273,10 @@ As an alternative approach, you could change your templates to match the new default context variables -- but it's a lot easier to just tell Django to use the variable you want. -You can now delete the ``index()``, ``detail()`` and ``results()`` -views from ``polls/views.py``. We don't need them anymore -- they have -been replaced by generic views. +You can now delete the ``index()``, ``detail()`` and ``results()`` views from +``polls/views.py``. We don't need them anymore -- they have been replaced by +generic views. You can also delete the import for ``HttpResponse``, which is no +longer required. Run the server, and use your new polling app based on generic views.