|
1 ===================================== |
|
2 Writing your first Django app, part 1 |
|
3 ===================================== |
|
4 |
|
5 Let's learn by example. |
|
6 |
|
7 Throughout this tutorial, we'll walk you through the creation of a basic |
|
8 poll application. |
|
9 |
|
10 It'll consist of two parts: |
|
11 |
|
12 * A public site that lets people view polls and vote in them. |
|
13 * An admin site that lets you add, change and delete polls. |
|
14 |
|
15 We'll assume you have :doc:`Django installed </intro/install>` already. You can |
|
16 tell Django is installed by running the Python interactive interpreter and |
|
17 typing ``import django``. If that command runs successfully, with no errors, |
|
18 Django is installed. |
|
19 |
|
20 .. admonition:: Where to get help: |
|
21 |
|
22 If you're having trouble going through this tutorial, please post a message |
|
23 to `django-users`__ or drop by `#django on irc.freenode.net`__ to chat |
|
24 with other Django users who might be able to help. |
|
25 |
|
26 __ http://groups.google.com/group/django-users |
|
27 __ irc://irc.freenode.net/django |
|
28 |
|
29 Creating a project |
|
30 ================== |
|
31 |
|
32 If this is your first time using Django, you'll have to take care of some |
|
33 initial setup. Namely, you'll need to auto-generate some code that establishes a |
|
34 Django :term:`project` -- a collection of settings for an instance of Django, |
|
35 including database configuration, Django-specific options and |
|
36 application-specific settings. |
|
37 |
|
38 From the command line, ``cd`` into a directory where you'd like to store your |
|
39 code, then run the command ``django-admin.py startproject mysite``. This will |
|
40 create a ``mysite`` directory in your current directory. |
|
41 |
|
42 .. admonition:: Script name may differ in distribution packages |
|
43 |
|
44 If you installed Django using a Linux distribution's package manager |
|
45 (e.g. apt-get or yum) ``django-admin.py`` may have been renamed to |
|
46 ``django-admin``. You may continue through this documentation by omitting |
|
47 ``.py`` from each command. |
|
48 |
|
49 .. admonition:: Mac OS X permissions |
|
50 |
|
51 If you're using Mac OS X, you may see the message "permission denied" when |
|
52 you try to run ``django-admin.py startproject``. This is because, on |
|
53 Unix-based systems like OS X, a file must be marked as "executable" before it |
|
54 can be run as a program. To do this, open Terminal.app and navigate (using |
|
55 the ``cd`` command) to the directory where :doc:`django-admin.py |
|
56 </ref/django-admin>` is installed, then run the command |
|
57 ``chmod +x django-admin.py``. |
|
58 |
|
59 .. note:: |
|
60 |
|
61 You'll need to avoid naming projects after built-in Python or Django |
|
62 components. In particular, this means you should avoid using names like |
|
63 ``django`` (which will conflict with Django itself) or ``test`` (which |
|
64 conflicts with a built-in Python package). |
|
65 |
|
66 :doc:`django-admin.py </ref/django-admin>` should be on your system path if you |
|
67 installed Django via ``python setup.py``. If it's not on your path, you can find |
|
68 it in ``site-packages/django/bin``, where ```site-packages``` is a directory |
|
69 within your Python installation. Consider symlinking to :doc:`django-admin.py |
|
70 </ref/django-admin>` from some place on your path, such as |
|
71 :file:`/usr/local/bin`. |
|
72 |
|
73 .. admonition:: Where should this code live? |
|
74 |
|
75 If your background is in PHP, you're probably used to putting code under the |
|
76 Web server's document root (in a place such as ``/var/www``). With Django, |
|
77 you don't do that. It's not a good idea to put any of this Python code |
|
78 within your Web server's document root, because it risks the possibility |
|
79 that people may be able to view your code over the Web. That's not good for |
|
80 security. |
|
81 |
|
82 Put your code in some directory **outside** of the document root, such as |
|
83 :file:`/home/mycode`. |
|
84 |
|
85 Let's look at what :djadmin:`startproject` created:: |
|
86 |
|
87 mysite/ |
|
88 __init__.py |
|
89 manage.py |
|
90 settings.py |
|
91 urls.py |
|
92 |
|
93 These files are: |
|
94 |
|
95 * :file:`__init__.py`: An empty file that tells Python that this directory |
|
96 should be considered a Python package. (Read `more about packages`_ in the |
|
97 official Python docs if you're a Python beginner.) |
|
98 |
|
99 * :file:`manage.py`: A command-line utility that lets you interact with this |
|
100 Django project in various ways. You can read all the details about |
|
101 :file:`manage.py` in :doc:`/ref/django-admin`. |
|
102 |
|
103 * :file:`settings.py`: Settings/configuration for this Django project. |
|
104 :doc:`/topics/settings` will tell you all about how settings work. |
|
105 |
|
106 * :file:`urls.py`: The URL declarations for this Django project; a "table of |
|
107 contents" of your Django-powered site. You can read more about URLs in |
|
108 :doc:`/topics/http/urls`. |
|
109 |
|
110 .. _more about packages: http://docs.python.org/tutorial/modules.html#packages |
|
111 |
|
112 The development server |
|
113 ---------------------- |
|
114 |
|
115 Let's verify this worked. Change into the :file:`mysite` directory, if you |
|
116 haven't already, and run the command ``python manage.py runserver``. You'll see |
|
117 the following output on the command line:: |
|
118 |
|
119 Validating models... |
|
120 0 errors found. |
|
121 |
|
122 Django version 1.0, using settings 'mysite.settings' |
|
123 Development server is running at http://127.0.0.1:8000/ |
|
124 Quit the server with CONTROL-C. |
|
125 |
|
126 You've started the Django development server, a lightweight Web server written |
|
127 purely in Python. We've included this with Django so you can develop things |
|
128 rapidly, without having to deal with configuring a production server -- such as |
|
129 Apache -- until you're ready for production. |
|
130 |
|
131 Now's a good time to note: DON'T use this server in anything resembling a |
|
132 production environment. It's intended only for use while developing. (We're in |
|
133 the business of making Web frameworks, not Web servers.) |
|
134 |
|
135 Now that the server's running, visit http://127.0.0.1:8000/ with your Web |
|
136 browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel. |
|
137 It worked! |
|
138 |
|
139 .. admonition:: Changing the port |
|
140 |
|
141 By default, the :djadmin:`runserver` command starts the development server |
|
142 on the internal IP at port 8000. |
|
143 |
|
144 If you want to change the server's port, pass |
|
145 it as a command-line argument. For instance, this command starts the server |
|
146 on port 8080: |
|
147 |
|
148 .. code-block:: bash |
|
149 |
|
150 python manage.py runserver 8080 |
|
151 |
|
152 If you want to change the server's IP, pass it along with the port. So to |
|
153 listen on all public IPs (useful if you want to show off your work on other |
|
154 computers), use: |
|
155 |
|
156 .. code-block:: bash |
|
157 |
|
158 python manage.py runserver 0.0.0.0:8000 |
|
159 |
|
160 Full docs for the development server can be found in the |
|
161 :djadmin:`runserver` reference. |
|
162 |
|
163 Database setup |
|
164 -------------- |
|
165 |
|
166 Now, edit :file:`settings.py`. It's a normal Python module with |
|
167 module-level variables representing Django settings. Change the |
|
168 following keys in the :setting:`DATABASES` ``'default'`` item to match |
|
169 your databases connection settings. |
|
170 |
|
171 * :setting:`ENGINE` -- Either |
|
172 ``'django.db.backends.postgresql_psycopg2'``, |
|
173 ``'django.db.backends.mysql'`` or |
|
174 ``'django.db.backends.sqlite3'``. Other backends are |
|
175 :setting:`also available <ENGINE>`. |
|
176 |
|
177 * :setting:`NAME` -- The name of your database. If you're using |
|
178 SQLite, the database will be a file on your computer; in that |
|
179 case, :setting:`NAME` should be the full absolute path, |
|
180 including filename, of that file. If the file doesn't exist, it |
|
181 will automatically be created when you synchronize the database |
|
182 for the first time (see below). |
|
183 |
|
184 When specifying the path, always use forward slashes, even on |
|
185 Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``). |
|
186 |
|
187 * :setting:`USER` -- Your database username (not used for SQLite). |
|
188 |
|
189 * :setting:`PASSWORD` -- Your database password (not used for |
|
190 SQLite). |
|
191 |
|
192 * :setting:`HOST` -- The host your database is on. Leave this as |
|
193 an empty string if your database server is on the same physical |
|
194 machine (not used for SQLite). |
|
195 |
|
196 If you're new to databases, we recommend simply using SQLite (by |
|
197 setting :setting:`ENGINE` to ``'django.db.backends.sqlite3'``). SQLite |
|
198 is included as part of Python 2.5 and later, so you won't need to |
|
199 install anything else. |
|
200 |
|
201 .. note:: |
|
202 |
|
203 If you're using PostgreSQL or MySQL, make sure you've created a database by |
|
204 this point. Do that with "``CREATE DATABASE database_name;``" within your |
|
205 database's interactive prompt. |
|
206 |
|
207 If you're using SQLite, you don't need to create anything beforehand - the |
|
208 database file will be created automatically when it is needed. |
|
209 |
|
210 While you're editing :file:`settings.py`, take note of the |
|
211 :setting:`INSTALLED_APPS` setting towards the bottom of the file. That variable |
|
212 holds the names of all Django applications that are activated in this Django |
|
213 instance. Apps can be used in multiple projects, and you can package and |
|
214 distribute them for use by others in their projects. |
|
215 |
|
216 By default, :setting:`INSTALLED_APPS` contains the following apps, all of which |
|
217 come with Django: |
|
218 |
|
219 * :mod:`django.contrib.auth` -- An authentication system. |
|
220 |
|
221 * :mod:`django.contrib.contenttypes` -- A framework for content types. |
|
222 |
|
223 * :mod:`django.contrib.sessions` -- A session framework. |
|
224 |
|
225 * :mod:`django.contrib.sites` -- A framework for managing multiple sites |
|
226 with one Django installation. |
|
227 |
|
228 * :mod:`django.contrib.messages` -- A messaging framework. |
|
229 |
|
230 These applications are included by default as a convenience for the common case. |
|
231 |
|
232 Each of these applications makes use of at least one database table, though, |
|
233 so we need to create the tables in the database before we can use them. To do |
|
234 that, run the following command: |
|
235 |
|
236 .. code-block:: bash |
|
237 |
|
238 python manage.py syncdb |
|
239 |
|
240 The :djadmin:`syncdb` command looks at the :setting:`INSTALLED_APPS` setting and |
|
241 creates any necessary database tables according to the database settings in your |
|
242 :file:`settings.py` file. You'll see a message for each database table it |
|
243 creates, and you'll get a prompt asking you if you'd like to create a superuser |
|
244 account for the authentication system. Go ahead and do that. |
|
245 |
|
246 If you're interested, run the command-line client for your database and type |
|
247 ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to |
|
248 display the tables Django created. |
|
249 |
|
250 .. admonition:: For the minimalists |
|
251 |
|
252 Like we said above, the default applications are included for the common |
|
253 case, but not everybody needs them. If you don't need any or all of them, |
|
254 feel free to comment-out or delete the appropriate line(s) from |
|
255 :setting:`INSTALLED_APPS` before running :djadmin:`syncdb`. The |
|
256 :djadmin:`syncdb` command will only create tables for apps in |
|
257 :setting:`INSTALLED_APPS`. |
|
258 |
|
259 .. _creating-models: |
|
260 |
|
261 Creating models |
|
262 =============== |
|
263 |
|
264 Now that your environment -- a "project" -- is set up, you're set to start |
|
265 doing work. |
|
266 |
|
267 Each application you write in Django consists of a Python package, somewhere |
|
268 on your `Python path`_, that follows a certain convention. Django comes with a |
|
269 utility that automatically generates the basic directory structure of an app, |
|
270 so you can focus on writing code rather than creating directories. |
|
271 |
|
272 .. admonition:: Projects vs. apps |
|
273 |
|
274 What's the difference between a project and an app? An app is a Web |
|
275 application that does something -- e.g., a Weblog system, a database of |
|
276 public records or a simple poll app. A project is a collection of |
|
277 configuration and apps for a particular Web site. A project can contain |
|
278 multiple apps. An app can be in multiple projects. |
|
279 |
|
280 Your apps can live anywhere on your `Python path`_. In this tutorial, we'll |
|
281 create our poll app in the :file:`mysite` directory for simplicity. |
|
282 |
|
283 To create your app, make sure you're in the :file:`mysite` directory and type |
|
284 this command: |
|
285 |
|
286 .. code-block:: bash |
|
287 |
|
288 python manage.py startapp polls |
|
289 |
|
290 That'll create a directory :file:`polls`, which is laid out like this:: |
|
291 |
|
292 polls/ |
|
293 __init__.py |
|
294 models.py |
|
295 tests.py |
|
296 views.py |
|
297 |
|
298 This directory structure will house the poll application. |
|
299 |
|
300 The first step in writing a database Web app in Django is to define your models |
|
301 -- essentially, your database layout, with additional metadata. |
|
302 |
|
303 .. admonition:: Philosophy |
|
304 |
|
305 A model is the single, definitive source of data about your data. It contains |
|
306 the essential fields and behaviors of the data you're storing. Django follows |
|
307 the :ref:`DRY Principle <dry>`. The goal is to define your data model in one |
|
308 place and automatically derive things from it. |
|
309 |
|
310 In our simple poll app, we'll create two models: polls and choices. A poll has |
|
311 a question and a publication date. A choice has two fields: the text of the |
|
312 choice and a vote tally. Each choice is associated with a poll. |
|
313 |
|
314 These concepts are represented by simple Python classes. Edit the |
|
315 :file:`polls/models.py` file so it looks like this:: |
|
316 |
|
317 from django.db import models |
|
318 |
|
319 class Poll(models.Model): |
|
320 question = models.CharField(max_length=200) |
|
321 pub_date = models.DateTimeField('date published') |
|
322 |
|
323 class Choice(models.Model): |
|
324 poll = models.ForeignKey(Poll) |
|
325 choice = models.CharField(max_length=200) |
|
326 votes = models.IntegerField() |
|
327 |
|
328 The code is straightforward. Each model is represented by a class that |
|
329 subclasses :class:`django.db.models.Model`. Each model has a number of class |
|
330 variables, each of which represents a database field in the model. |
|
331 |
|
332 Each field is represented by an instance of a :class:`~django.db.models.Field` |
|
333 class -- e.g., :class:`~django.db.models.CharField` for character fields and |
|
334 :class:`~django.db.models.DateTimeField` for datetimes. This tells Django what |
|
335 type of data each field holds. |
|
336 |
|
337 The name of each :class:`~django.db.models.Field` instance (e.g. ``question`` or |
|
338 ``pub_date`` ) is the field's name, in machine-friendly format. You'll use this |
|
339 value in your Python code, and your database will use it as the column name. |
|
340 |
|
341 You can use an optional first positional argument to a |
|
342 :class:`~django.db.models.Field` to designate a human-readable name. That's used |
|
343 in a couple of introspective parts of Django, and it doubles as documentation. |
|
344 If this field isn't provided, Django will use the machine-readable name. In this |
|
345 example, we've only defined a human-readable name for ``Poll.pub_date``. For all |
|
346 other fields in this model, the field's machine-readable name will suffice as |
|
347 its human-readable name. |
|
348 |
|
349 Some :class:`~django.db.models.Field` classes have required elements. |
|
350 :class:`~django.db.models.CharField`, for example, requires that you give it a |
|
351 :attr:`~django.db.models.Field.max_length`. That's used not only in the database |
|
352 schema, but in validation, as we'll soon see. |
|
353 |
|
354 Finally, note a relationship is defined, using |
|
355 :class:`~django.db.models.ForeignKey`. That tells Django each Choice is related |
|
356 to a single Poll. Django supports all the common database relationships: |
|
357 many-to-ones, many-to-manys and one-to-ones. |
|
358 |
|
359 .. _`Python path`: http://docs.python.org/tutorial/modules.html#the-module-search-path |
|
360 |
|
361 Activating models |
|
362 ================= |
|
363 |
|
364 That small bit of model code gives Django a lot of information. With it, Django |
|
365 is able to: |
|
366 |
|
367 * Create a database schema (``CREATE TABLE`` statements) for this app. |
|
368 * Create a Python database-access API for accessing Poll and Choice objects. |
|
369 |
|
370 But first we need to tell our project that the ``polls`` app is installed. |
|
371 |
|
372 .. admonition:: Philosophy |
|
373 |
|
374 Django apps are "pluggable": You can use an app in multiple projects, and |
|
375 you can distribute apps, because they don't have to be tied to a given |
|
376 Django installation. |
|
377 |
|
378 Edit the :file:`settings.py` file again, and change the |
|
379 :setting:`INSTALLED_APPS` setting to include the string ``'polls'``. So |
|
380 it'll look like this:: |
|
381 |
|
382 INSTALLED_APPS = ( |
|
383 'django.contrib.auth', |
|
384 'django.contrib.contenttypes', |
|
385 'django.contrib.sessions', |
|
386 'django.contrib.sites', |
|
387 'polls' |
|
388 ) |
|
389 |
|
390 Now Django knows to include the ``polls`` app. Let's run another |
|
391 command: |
|
392 |
|
393 .. code-block:: bash |
|
394 |
|
395 python manage.py sql polls |
|
396 |
|
397 You should see something similar to the following (the ``CREATE TABLE`` SQL |
|
398 statements for the polls app): |
|
399 |
|
400 .. code-block:: sql |
|
401 |
|
402 BEGIN; |
|
403 CREATE TABLE "polls_poll" ( |
|
404 "id" serial NOT NULL PRIMARY KEY, |
|
405 "question" varchar(200) NOT NULL, |
|
406 "pub_date" timestamp with time zone NOT NULL |
|
407 ); |
|
408 CREATE TABLE "polls_choice" ( |
|
409 "id" serial NOT NULL PRIMARY KEY, |
|
410 "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"), |
|
411 "choice" varchar(200) NOT NULL, |
|
412 "votes" integer NOT NULL |
|
413 ); |
|
414 COMMIT; |
|
415 |
|
416 Note the following: |
|
417 |
|
418 * The exact output will vary depending on the database you are using. |
|
419 |
|
420 * Table names are automatically generated by combining the name of the app |
|
421 (``polls``) and the lowercase name of the model -- ``poll`` and |
|
422 ``choice``. (You can override this behavior.) |
|
423 |
|
424 * Primary keys (IDs) are added automatically. (You can override this, too.) |
|
425 |
|
426 * By convention, Django appends ``"_id"`` to the foreign key field name. |
|
427 Yes, you can override this, as well. |
|
428 |
|
429 * The foreign key relationship is made explicit by a ``REFERENCES`` |
|
430 statement. |
|
431 |
|
432 * It's tailored to the database you're using, so database-specific field |
|
433 types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or |
|
434 ``integer primary key`` (SQLite) are handled for you automatically. Same |
|
435 goes for quoting of field names -- e.g., using double quotes or single |
|
436 quotes. The author of this tutorial runs PostgreSQL, so the example |
|
437 output is in PostgreSQL syntax. |
|
438 |
|
439 * The :djadmin:`sql` command doesn't actually run the SQL in your database - |
|
440 it just prints it to the screen so that you can see what SQL Django thinks |
|
441 is required. If you wanted to, you could copy and paste this SQL into your |
|
442 database prompt. However, as we will see shortly, Django provides an |
|
443 easier way of committing the SQL to the database. |
|
444 |
|
445 If you're interested, also run the following commands: |
|
446 |
|
447 * :djadmin:`python manage.py validate <validate>` -- Checks for any errors |
|
448 in the construction of your models. |
|
449 |
|
450 * :djadmin:`python manage.py sqlcustom polls <sqlcustom>` -- Outputs any |
|
451 :ref:`custom SQL statements <initial-sql>` (such as table modifications or |
|
452 constraints) that are defined for the application. |
|
453 |
|
454 * :djadmin:`python manage.py sqlclear polls <sqlclear>` -- Outputs the |
|
455 necessary ``DROP TABLE`` statements for this app, according to which |
|
456 tables already exist in your database (if any). |
|
457 |
|
458 * :djadmin:`python manage.py sqlindexes polls <sqlindexes>` -- Outputs the |
|
459 ``CREATE INDEX`` statements for this app. |
|
460 |
|
461 * :djadmin:`python manage.py sqlall polls <sqlall>` -- A combination of all |
|
462 the SQL from the :djadmin:`sql`, :djadmin:`sqlcustom`, and |
|
463 :djadmin:`sqlindexes` commands. |
|
464 |
|
465 Looking at the output of those commands can help you understand what's actually |
|
466 happening under the hood. |
|
467 |
|
468 Now, run :djadmin:`syncdb` again to create those model tables in your database: |
|
469 |
|
470 .. code-block:: bash |
|
471 |
|
472 python manage.py syncdb |
|
473 |
|
474 The :djadmin:`syncdb` command runs the sql from 'sqlall' on your database for |
|
475 all apps in :setting:`INSTALLED_APPS` that don't already exist in your database. |
|
476 This creates all the tables, initial data and indexes for any apps you have |
|
477 added to your project since the last time you ran syncdb. :djadmin:`syncdb` can |
|
478 be called as often as you like, and it will only ever create the tables that |
|
479 don't exist. |
|
480 |
|
481 Read the :doc:`django-admin.py documentation </ref/django-admin>` for full |
|
482 information on what the ``manage.py`` utility can do. |
|
483 |
|
484 Playing with the API |
|
485 ==================== |
|
486 |
|
487 Now, let's hop into the interactive Python shell and play around with the free |
|
488 API Django gives you. To invoke the Python shell, use this command: |
|
489 |
|
490 .. code-block:: bash |
|
491 |
|
492 python manage.py shell |
|
493 |
|
494 We're using this instead of simply typing "python", because ``manage.py`` sets |
|
495 up the project's environment for you. "Setting up the environment" involves two |
|
496 things: |
|
497 |
|
498 * Putting ``polls`` on ``sys.path``. For flexibility, several pieces of |
|
499 Django refer to projects in Python dotted-path notation (e.g. |
|
500 ``'polls.models'``). In order for this to work, the ``polls`` |
|
501 package has to be on ``sys.path``. |
|
502 |
|
503 We've already seen one example of this: the :setting:`INSTALLED_APPS` |
|
504 setting is a list of packages in dotted-path notation. |
|
505 |
|
506 * Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives |
|
507 Django the path to your ``settings.py`` file. |
|
508 |
|
509 .. admonition:: Bypassing manage.py |
|
510 |
|
511 If you'd rather not use ``manage.py``, no problem. Just make sure ``mysite`` |
|
512 and ``polls`` are at the root level on the Python path (i.e., ``import mysite`` |
|
513 and ``import polls`` work) and set the ``DJANGO_SETTINGS_MODULE`` environment |
|
514 variable to ``mysite.settings``. |
|
515 |
|
516 For more information on all of this, see the :doc:`django-admin.py |
|
517 documentation </ref/django-admin>`. |
|
518 |
|
519 Once you're in the shell, explore the :doc:`database API </topics/db/queries>`:: |
|
520 |
|
521 >>> from polls.models import Poll, Choice # Import the model classes we just wrote. |
|
522 |
|
523 # No polls are in the system yet. |
|
524 >>> Poll.objects.all() |
|
525 [] |
|
526 |
|
527 # Create a new Poll. |
|
528 >>> import datetime |
|
529 >>> p = Poll(question="What's up?", pub_date=datetime.datetime.now()) |
|
530 |
|
531 # Save the object into the database. You have to call save() explicitly. |
|
532 >>> p.save() |
|
533 |
|
534 # Now it has an ID. Note that this might say "1L" instead of "1", depending |
|
535 # on which database you're using. That's no biggie; it just means your |
|
536 # database backend prefers to return integers as Python long integer |
|
537 # objects. |
|
538 >>> p.id |
|
539 1 |
|
540 |
|
541 # Access database columns via Python attributes. |
|
542 >>> p.question |
|
543 "What's up?" |
|
544 >>> p.pub_date |
|
545 datetime.datetime(2007, 7, 15, 12, 00, 53) |
|
546 |
|
547 # Change values by changing the attributes, then calling save(). |
|
548 >>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0) |
|
549 >>> p.save() |
|
550 |
|
551 # objects.all() displays all the polls in the database. |
|
552 >>> Poll.objects.all() |
|
553 [<Poll: Poll object>] |
|
554 |
|
555 |
|
556 Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful representation |
|
557 of this object. Let's fix that by editing the polls model (in the |
|
558 ``polls/models.py`` file) and adding a |
|
559 :meth:`~django.db.models.Model.__unicode__` method to both ``Poll`` and |
|
560 ``Choice``:: |
|
561 |
|
562 class Poll(models.Model): |
|
563 # ... |
|
564 def __unicode__(self): |
|
565 return self.question |
|
566 |
|
567 class Choice(models.Model): |
|
568 # ... |
|
569 def __unicode__(self): |
|
570 return self.choice |
|
571 |
|
572 It's important to add :meth:`~django.db.models.Model.__unicode__` methods to |
|
573 your models, not only for your own sanity when dealing with the interactive |
|
574 prompt, but also because objects' representations are used throughout Django's |
|
575 automatically-generated admin. |
|
576 |
|
577 .. admonition:: Why :meth:`~django.db.models.Model.__unicode__` and not |
|
578 :meth:`~django.db.models.Model.__str__`? |
|
579 |
|
580 If you're familiar with Python, you might be in the habit of adding |
|
581 :meth:`~django.db.models.Model.__str__` methods to your classes, not |
|
582 :meth:`~django.db.models.Model.__unicode__` methods. We use |
|
583 :meth:`~django.db.models.Model.__unicode__` here because Django models deal |
|
584 with Unicode by default. All data stored in your database is converted to |
|
585 Unicode when it's returned. |
|
586 |
|
587 Django models have a default :meth:`~django.db.models.Model.__str__` method |
|
588 that calls :meth:`~django.db.models.Model.__unicode__` and converts the |
|
589 result to a UTF-8 bytestring. This means that ``unicode(p)`` will return a |
|
590 Unicode string, and ``str(p)`` will return a normal string, with characters |
|
591 encoded as UTF-8. |
|
592 |
|
593 If all of this is jibberish to you, just remember to add |
|
594 :meth:`~django.db.models.Model.__unicode__` methods to your models. With any |
|
595 luck, things should Just Work for you. |
|
596 |
|
597 Note these are normal Python methods. Let's add a custom method, just for |
|
598 demonstration:: |
|
599 |
|
600 import datetime |
|
601 # ... |
|
602 class Poll(models.Model): |
|
603 # ... |
|
604 def was_published_today(self): |
|
605 return self.pub_date.date() == datetime.date.today() |
|
606 |
|
607 Note the addition of ``import datetime`` to reference Python's standard |
|
608 ``datetime`` module. |
|
609 |
|
610 Save these changes and start a new Python interactive shell by running |
|
611 ``python manage.py shell`` again:: |
|
612 |
|
613 >>> from polls.models import Poll, Choice |
|
614 |
|
615 # Make sure our __unicode__() addition worked. |
|
616 >>> Poll.objects.all() |
|
617 [<Poll: What's up?>] |
|
618 |
|
619 # Django provides a rich database lookup API that's entirely driven by |
|
620 # keyword arguments. |
|
621 >>> Poll.objects.filter(id=1) |
|
622 [<Poll: What's up?>] |
|
623 >>> Poll.objects.filter(question__startswith='What') |
|
624 [<Poll: What's up?>] |
|
625 |
|
626 # Get the poll whose year is 2007. |
|
627 >>> Poll.objects.get(pub_date__year=2007) |
|
628 <Poll: What's up?> |
|
629 |
|
630 >>> Poll.objects.get(id=2) |
|
631 Traceback (most recent call last): |
|
632 ... |
|
633 DoesNotExist: Poll matching query does not exist. |
|
634 |
|
635 # Lookup by a primary key is the most common case, so Django provides a |
|
636 # shortcut for primary-key exact lookups. |
|
637 # The following is identical to Poll.objects.get(id=1). |
|
638 >>> Poll.objects.get(pk=1) |
|
639 <Poll: What's up?> |
|
640 |
|
641 # Make sure our custom method worked. |
|
642 >>> p = Poll.objects.get(pk=1) |
|
643 >>> p.was_published_today() |
|
644 False |
|
645 |
|
646 # Give the Poll a couple of Choices. The create call constructs a new |
|
647 # choice object, does the INSERT statement, adds the choice to the set |
|
648 # of available choices and returns the new Choice object. Django creates |
|
649 # a set to hold the "other side" of a ForeignKey relation |
|
650 # (e.g. a poll's choices) which can be accessed via the API. |
|
651 >>> p = Poll.objects.get(pk=1) |
|
652 |
|
653 # Display any choices from the related object set -- none so far. |
|
654 >>> p.choice_set.all() |
|
655 [] |
|
656 |
|
657 # Create three choices. |
|
658 >>> p.choice_set.create(choice='Not much', votes=0) |
|
659 <Choice: Not much> |
|
660 >>> p.choice_set.create(choice='The sky', votes=0) |
|
661 <Choice: The sky> |
|
662 >>> c = p.choice_set.create(choice='Just hacking again', votes=0) |
|
663 |
|
664 # Choice objects have API access to their related Poll objects. |
|
665 >>> c.poll |
|
666 <Poll: What's up?> |
|
667 |
|
668 # And vice versa: Poll objects get access to Choice objects. |
|
669 >>> p.choice_set.all() |
|
670 [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] |
|
671 >>> p.choice_set.count() |
|
672 3 |
|
673 |
|
674 # The API automatically follows relationships as far as you need. |
|
675 # Use double underscores to separate relationships. |
|
676 # This works as many levels deep as you want; there's no limit. |
|
677 # Find all Choices for any poll whose pub_date is in 2007. |
|
678 >>> Choice.objects.filter(poll__pub_date__year=2007) |
|
679 [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] |
|
680 |
|
681 # Let's delete one of the choices. Use delete() for that. |
|
682 >>> c = p.choice_set.filter(choice__startswith='Just hacking') |
|
683 >>> c.delete() |
|
684 |
|
685 For more information on model relations, see :doc:`Accessing related objects |
|
686 </ref/models/relations>`. For full details on the database API, see our |
|
687 :doc:`Database API reference </topics/db/queries>`. |
|
688 |
|
689 When you're comfortable with the API, read :doc:`part 2 of this tutorial |
|
690 </intro/tutorial02>` to get Django's automatic admin working. |