Permalink
Browse files

magic-removal: Fixes #1599, Refs #1464 -- Updated all tutorials for n…

…ew syntax, changes in manage.py, etc.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2632 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent 218035c commit d1083f15fbdf073d768677f683a1e3b5136e3e41 @freakboy3742 freakboy3742 committed Apr 8, 2006
Showing with 102 additions and 92 deletions.
  1. +28 −22 docs/tutorial01.txt
  2. +4 −12 docs/tutorial02.txt
  3. +38 −34 docs/tutorial03.txt
  4. +32 −24 docs/tutorial04.txt
View
@@ -24,7 +24,7 @@ Initial setup
If this is your first time using Django, you'll have to take care of some
initial setup.
-Run the command ``django-admin.py startproject myproject``. That'll create a
+Run the command ``django-admin.py startproject myproject``. This will create a
``myproject`` directory in your current directory.
(``django-admin.py`` should be on your system path if you installed Django via
@@ -125,9 +125,10 @@ database's connection parameters:
database's interactive prompt.
While you're editing ``settings.py``, take note of the ``INSTALLED_APPS``
-setting. That variable holds the names of all Django applications that are
-activated in this Django instance. Apps can be used in multiple projects,
-and you can distribute them.
+setting towards the bottom of the file. That variable holds the names of all
+Django applications that are activated in this Django instance. Apps can be
+used in multiple projects, and you can package and distribute them for use
+by others in their projects.
By default, ``INSTALLED_APPS`` contains the following apps, all of which come
with Django::
@@ -285,12 +286,9 @@ to include the string ``'myproject.polls'``. So it'll look like this::
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
- 'myproject.polls',
+ 'myproject.polls'
)
-(Don't forget the trailing comma, because of Python's rule about single-value
-tuples: Without a trailing comma, Python wouldn't know this was a tuple.)
-
Now Django knows ``myproject`` includes the ``polls`` app. Let's run another command::
python manage.py sql polls
@@ -331,6 +329,12 @@ Note the following:
quotes. The author of this tutorial runs PostgreSQL, so the example
output is in PostgreSQL syntax.
+ * The `sql` command doesn't actually run the SQL in your database - it just
+ prints it to the screen so that you can see what SQL Django thinks is required.
+ If you wanted to, you could copy and paste this SQL into your database prompt.
+ However, as we will see shortly, Django provides an easier way of committing
+ the SQL to the database.
+
If you're interested, also run the following commands:
* ``python manage.py sqlinitialdata polls`` -- Outputs any initial data
@@ -343,8 +347,8 @@ If you're interested, also run the following commands:
* ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
statements for this app.
- * ``python manage.py sqlall polls`` -- A combination of 'sql' and
- 'sqlinitialdata'.
+ * ``python manage.py sqlall polls`` -- A combination of all the SQL from
+ the 'sql', 'sqlinitialdata', and 'sqlindexes' commands.
Looking at the output of those commands can help you understand what's actually
happening under the hood.
@@ -353,9 +357,11 @@ Now, run ``syncdb`` again to create those model tables in your database::
python manage.py syncdb
-As a review, the ``syncdb`` command creates the tables for all apps in
-``INSTALLED_APPS`` that don't already exist in your database. So you can run it
-again and again, and it'll always just create the tables that don't exist.
+The ``syncdb`` command runs the sql from 'sqlall' on your database for all apps
+in ``INSTALLED_APPS`` that don't already exist in your database. This creates
+all the tables, initial data and indexes for any apps you have added to your
+project since the last time you ran syncdb. ``syncdb`` can be called as often
+as you like, and it will only ever create the tables that don't exist.
Read the `django-admin.py documentation`_ for full information on what the
``manage.py`` utility can do.
@@ -454,10 +460,11 @@ representations are used throughout Django's automatically-generated admin.
Note these are normal Python methods. Let's add a custom method, just for
demonstration::
+ import datetime
+ # ...
class Poll(models.Model):
# ...
def was_published_today(self):
- import datetime
return self.pub_date.date() == datetime.date.today()
Note the addition of ``import datetime`` to reference Python's standard
@@ -488,8 +495,6 @@ Let's jump back into the Python interactive shell by running
Traceback (most recent call last):
...
DoesNotExist: Poll does not exist for {'id': 2}
- >>> Poll.objects.filter(question__startswith='What')
- [What's up?]
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
@@ -502,14 +507,15 @@ Let's jump back into the Python interactive shell by running
>>> p.was_published_today()
False
- # Give the Poll a couple of Choices. Each one of these method calls does an
- # INSERT statement behind the scenes and returns the new Choice object.
+ # Give the Poll a couple of Choices. The create call constructs a new
+ # choice object, does the INSERT statement, adds the choice to the set
+ # of available choices and returns the new Choice object.
>>> p = Poll.objects.get(pk=1)
- >>> p.choice_set.add(choice='Not much', votes=0)
+ >>> p.choice_set.create(choice='Not much', votes=0)
Not much
- >>> p.choice_set.add(choice='The sky', votes=0)
+ >>> p.choice_set.create(choice='The sky', votes=0)
The sky
- >>> c = p.choice_set.add(choice='Just hacking again', votes=0)
+ >>> c = p.choice_set.create(choice='Just hacking again', votes=0)
# Choice objects have API access to their related Poll objects.
>>> c.poll
@@ -518,7 +524,7 @@ Let's jump back into the Python interactive shell by running
# And vice versa: Poll objects get access to Choice objects.
>>> p.choice_set.all()
[Not much, The sky, Just hacking again]
- >>> p.choice_set.all().count()
+ >>> p.choice_set.count()
3
# The API automatically follows relationships as far as you need.
View
@@ -31,22 +31,13 @@ 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 ``INSTALLED_APPS`` setting.
- * Run the command ``python manage.py install admin``. This will create an
- extra database table that the admin needs.
+ * Run ``python manage.py syncdb``. Since you have added a new application
+ to ``INSTALLED_APPS``, the database tables need to be updated.
* Edit your ``myproject/urls.py`` file and uncomment the line below
"Uncomment this for admin:". 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.
-Create a user account
-=====================
-
-Run the following command to create a superuser account for your admin site::
-
- python manage.py createsuperuser
-
-The script will prompt you for a username, e-mail address and password (twice).
-
Start the development server
============================
@@ -96,7 +87,8 @@ creating an empty class means "give this object an admin interface using
all the default options."
Now reload the Django admin page to see your changes. Note that you don't have
-to restart the development server -- it auto-reloads code.
+to restart the development server -- the server will auto-reloads your project,
+so any modifications code will be seen immediately in your browser.
Explore the free admin functionality
====================================
View
@@ -74,25 +74,27 @@ Time for an example. Edit ``myproject/urls.py`` so it looks like this::
urlpatterns = patterns('',
(r'^polls/$', 'myproject.polls.views.index'),
- (r'^polls/(\d+)/$', 'myproject.polls.views.detail'),
- (r'^polls/(\d+)/results/$', 'myproject.polls.views.results'),
- (r'^polls/(\d+)/vote/$', 'myproject.polls.views.vote'),
+ (r'^polls/(?P<poll_id>\d+)/$', 'myproject.polls.views.detail'),
+ (r'^polls/(?P<poll_id>\d+)/results/$', 'myproject.polls.views.results'),
+ (r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.polls.views.vote'),
)
This is worth a review. When somebody requests a page from your Web site --
say, "/polls/23/", Django will load this Python module, because it's pointed to
by the ``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/(\d+)/$'`` -- it loads the
+expression that matches -- ``r'^polls/(?P<poll_id>\d+)/$'`` -- it loads the
associated Python package/module: ``myproject.polls.views.detail``. That
corresponds to the function ``detail()`` in ``myproject/polls/views.py``.
Finally, it calls that ``detail()`` function like so::
detail(request=<HttpRequest object>, poll_id='23')
-The ``poll_id='23'`` part comes from ``(\d+)``. Using parenthesis around a
+The ``poll_id='23'`` part comes from ``(?P<poll_id>\d+)``. Using parenthesis around a
pattern "captures" the text matched by that pattern and sends it as an argument
-to the view function.
+to the view function; the ``?P<poll_id>`` defines the name that will be used to
+identify the matched pattern; and \d+ is a regular experession to match a sequence of
+digits (i.e., a number).
Because the URL patterns are regular expressions, there really is no limit on
what you can do with them. And there's no need to add URL cruft such as
@@ -185,29 +187,29 @@ in 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 django.models.polls import polls
- from django.http import HttpResponse
+ from myproject.polls.models import Poll
+ from django.http import HttpResponse
- def index(request):
- latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5)
- output = ', '.join([p.question for p in latest_poll_list])
- return HttpResponse(output)
+ def index(request):
+ latest_poll_list = Poll.objects.all().order_by('-pub_date')
+ output = ', '.join([p.question for p in latest_poll_list])
+ return HttpResponse(output)
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::
- from django.template import Context, loader
- from django.models.polls import polls
- from django.http import HttpResponse
+ from django.template import Context, loader
+ from myproject.polls.models import Poll
+ from django.http import HttpResponse
- def index(request):
- latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5)
- t = loader.get_template('polls/index')
- c = Context({
- 'latest_poll_list': latest_poll_list,
- })
- return HttpResponse(t.render(c))
+ def index(request):
+ latest_poll_list = Poll.objects.all().order_by('-pub_date')
+ t = loader.get_template('polls/index')
+ c = Context({
+ 'latest_poll_list': latest_poll_list,
+ })
+ return HttpResponse(t.render(c))
That code loads the template called "polls/index" and passes it a context. The
context is a dictionary mapping template variable names to Python objects.
@@ -254,11 +256,11 @@ It's a very common idiom to load a template, fill a context and return an
``HttpResponse`` object with the result of the rendered template. Django
provides a shortcut. Here's the full ``index()`` view, rewritten::
- from django.shortcuts import render_to_response
- from django.models.polls import polls
+ from django.shortcuts import render_to_response
+ from myproject.polls.models import Poll
- def index(request):
- latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5)
+ def index(request):
+ latest_poll_list = Poll.objects.all().order_by('-pub_date')
return render_to_response('polls/index', {'latest_poll_list': latest_poll_list})
Note that we no longer need to import ``loader``, ``Context`` or
@@ -275,12 +277,13 @@ Now, let's tackle the poll detail view -- the page that displays the question
for a given poll. Here's the view::
from django.http import Http404
- def detail(request, poll_id):
- try:
- p = polls.get_object(pk=poll_id)
- except polls.PollDoesNotExist:
- raise Http404
- return render_to_response('polls/detail', {'poll': p})
+ # ...
+ def detail(request, poll_id):
+ try:
+ p = Poll.objects.get(pk=poll_id)
+ except Poll.DoesNotExist:
+ raise Http404
+ return render_to_response('polls/detail', {'poll': p})
The new concept here: The view raises the ``django.http.Http404``
exception if a poll with the requested ID doesn't exist.
@@ -292,9 +295,10 @@ It's a very common idiom to use ``get_object()`` and raise ``Http404`` if the
object doesn't exist. Django provides a shortcut. Here's the ``detail()`` view,
rewritten::
- from django.shortcuts import get_object_or_404
+ from django.shortcuts import render_to_response, get_object_or_404
+ # ...
def detail(request, poll_id):
- p = get_object_or_404(polls, pk=poll_id)
+ p = get_object_or_404(Poll, pk=poll_id)
return render_to_response('polls/detail', {'poll': p})
The ``get_object_or_404()`` function takes a Django model module as its first
Oops, something went wrong. Retry.

0 comments on commit d1083f1

Please sign in to comment.