diff -r 5ff1fc726848 -r c6bca38c1cbf parts/django/docs/intro/tutorial02.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parts/django/docs/intro/tutorial02.txt Sat Jan 08 11:20:57 2011 +0530 @@ -0,0 +1,465 @@ +===================================== +Writing your first Django app, part 2 +===================================== + +This tutorial begins where :doc:`Tutorial 1 ` left off. We're +continuing the Web-poll application and will focus on Django's +automatically-generated admin site. + +.. admonition:: Philosophy + + Generating admin sites for your staff or clients to add, change and delete + content is tedious work that doesn't require much creativity. For that + reason, Django entirely automates creation of admin interfaces for models. + + Django was written in a newsroom environment, with a very clear separation + between "content publishers" and the "public" site. Site managers use the + system to add news stories, events, sports scores, etc., and that content is + displayed on the public site. Django solves the problem of creating a + unified interface for site administrators to edit content. + + The admin isn't necessarily intended to be used by site visitors; it's for + site managers. + +Activate the admin site +======================= + +The Django admin site is not activated by default -- it's an opt-in thing. To +activate the admin site for your installation, do these three things: + + * Add ``"django.contrib.admin"`` to your :setting:`INSTALLED_APPS` setting. + + * Run ``python manage.py syncdb``. Since you have added a new application + to :setting:`INSTALLED_APPS`, the database tables need to be updated. + + * Edit your ``mysite/urls.py`` file and uncomment the lines that reference + the admin -- there are three lines in total to uncomment. This file is a + URLconf; we'll dig into URLconfs in the next tutorial. For now, all you + need to know is that it maps URL roots to applications. In the end, you + should have a ``urls.py`` file that looks like this: + + .. versionchanged:: 1.1 + The method for adding admin urls has changed in Django 1.1. + + .. parsed-literal:: + + from django.conf.urls.defaults import * + + # Uncomment the next two lines to enable the admin: + **from django.contrib import admin** + **admin.autodiscover()** + + urlpatterns = patterns('', + # Example: + # (r'^mysite/', include('mysite.foo.urls')), + + # Uncomment the admin/doc line below and add 'django.contrib.admindocs' + # to INSTALLED_APPS to enable admin documentation: + # (r'^admin/doc/', include('django.contrib.admindocs.urls')), + + # Uncomment the next line to enable the admin: + **(r'^admin/', include(admin.site.urls)),** + ) + + (The bold lines are the ones that needed to be uncommented.) + +Start the development server +============================ + +Let's start the development server and explore the admin site. + +Recall from Tutorial 1 that you start the development server like so: + +.. code-block:: bash + + python manage.py runserver + +Now, open a Web browser and go to "/admin/" on your local domain -- e.g., +http://127.0.0.1:8000/admin/. You should see the admin's login screen: + +.. image:: _images/admin01.png + :alt: Django admin login screen + +Enter the admin site +==================== + +Now, try logging in. (You created a superuser account in the first part of this +tutorial, remember? If you didn't create one or forgot the password you can +:ref:`create another one `.) You should see +the Django admin index page: + +.. image:: _images/admin02t.png + :alt: Django admin index page + +You should see a few other types of editable content, including groups, users +and sites. These are core features Django ships with by default. + +Make the poll app modifiable in the admin +========================================= + +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`` +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 polls.models import Poll + from django.contrib import admin + + admin.site.register(Poll) + +You'll need to restart the development server to see your changes. Normally, +the server auto-reloads code every time you modify a file, but the action of +creating a new file doesn't trigger the auto-reloading logic. + +Explore the free admin functionality +==================================== + +Now that we've registered ``Poll``, Django knows that it should be displayed on +the admin index page: + +.. image:: _images/admin03t.png + :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: + +.. image:: _images/admin04t.png + :alt: Polls change list page + +Click the "What's up?" poll to edit it: + +.. image:: _images/admin05t.png + :alt: Editing form for poll object + +Things to note here: + + * The form is automatically generated from the Poll model. + + * The different model field types (:class:`~django.db.models.DateTimeField`, + :class:`~django.db.models.CharField`) correspond to the appropriate HTML + input widget. Each type of field knows how to display itself in the Django + admin. + + * Each :class:`~django.db.models.DateTimeField` gets free JavaScript + shortcuts. Dates get a "Today" shortcut and calendar popup, and times get + a "Now" shortcut and a convenient popup that lists commonly entered times. + +The bottom part of the page gives you a couple of options: + + * Save -- Saves changes and returns to the change-list page for this type of + object. + + * Save and continue editing -- Saves changes and reloads the admin page for + this object. + + * Save and add another -- Saves changes and loads a new, blank form for this + type of object. + + * Delete -- Displays a delete confirmation page. + +Change the "Date published" by clicking the "Today" and "Now" shortcuts. Then +click "Save and continue editing." Then click "History" in the upper right. +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: + +.. image:: _images/admin06t.png + :alt: History page for poll object + +Customize the admin form +======================== + +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. + +Let's see how this works by re-ordering the fields on the edit form. Replace +the ``admin.site.register(Poll)`` line with:: + + class PollAdmin(admin.ModelAdmin): + fields = ['pub_date', 'question'] + + admin.site.register(Poll, PollAdmin) + +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 +admin options for an object. + +This particular change above makes the "Publication date" come before the +"Question" field: + +.. image:: _images/admin07.png + :alt: Fields have been reordered + +This isn't impressive with only two fields, but for admin forms with dozens +of fields, choosing an intuitive order is an important usability detail. + +And speaking of forms with dozens of fields, you might want to split the form +up into fieldsets:: + + class PollAdmin(admin.ModelAdmin): + fieldsets = [ + (None, {'fields': ['question']}), + ('Date information', {'fields': ['pub_date']}), + ] + + admin.site.register(Poll, PollAdmin) + +The first element of each tuple in ``fieldsets`` is the title of the fieldset. +Here's what our form looks like now: + +.. image:: _images/admin08t.png + :alt: Form has fieldsets now + +You can assign arbitrary HTML classes to each fieldset. Django provides a +``"collapse"`` class that displays a particular fieldset initially collapsed. +This is useful when you have a long form that contains a number of fields that +aren't commonly used:: + + class PollAdmin(admin.ModelAdmin): + fieldsets = [ + (None, {'fields': ['question']}), + ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), + ] + +.. image:: _images/admin09.png + :alt: Fieldset is initially collapsed + +Adding related objects +====================== + +OK, we have our Poll admin page. But a ``Poll`` has multiple ``Choices``, and +the admin page doesn't display choices. + +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 polls.models import Choice + + admin.site.register(Choice) + +Now "Choices" is an available option in the Django admin. The "Add choice" form +looks like this: + +.. image:: _images/admin10.png + :alt: Choice admin page + +In that form, the "Poll" field is a select box containing every poll in the +database. Django knows that a :class:`~django.db.models.ForeignKey` should be +represented in the admin as a ``