Writing your first Django app, part 1
编写你的第一个Django程序,第一部分
Let’s learn by example.
从示例程序开始吧。
Throughout this tutorial, we’ll walk you through the creation of a basic poll application.
通过这本新手入门,我们会从头至尾向你介绍怎样创建一个基本的投票程序。
It’ll consist of two parts:
• A public site that lets people view polls and vote in them.
• An admin site that lets you add, change and delete polls.
这个程序包含了两个部分:
一个能够让用户查看投票选项并进行投票的前台。
一个能够进行投票管理的后台。
We’ll assume you have Django installed already. You can tell Django is installed by running the Python interactive interpreter and typing import django. If that command runs successfully, with no errors, Django is installed.
我们假设你已经安装了Django。你可以通过运行Python命令行交互界面并输入import django来确认是否已经安装了Django。如果刚才的命令成功运行了,表示Django已经安装完成。
Where to get help:
If you’re having trouble going through this tutorial, please post a message to django-users or drop by #django on irc.freenode.net to chat with other Django users who might be able to help.
从哪里获取帮助:
如果你在阅读这篇新手入门的时候遇到任何困难,请在Django的Google小组留言或是访问Django的IRC,从其他的用户那里获得帮助。
Creating a project
创建项目
If this is your first time using Django, you’ll have to take care of some initial setup. Namely, you’ll need to auto-generate some code that establishes a Django project – a collection of settings for an instance of Django, including database configuration, Django-specific options and application-specific settings.
如果这是你第一次使用Django,你需要注意一下初始化设置。也就是说,你需要自动创建一些Django项目初始化的代码——包括数据库设置、Django特性设置以及程序特性设置。
From the command line, cd into a directory where you’d like to store your code, then run the command django-admin.py startproject mysite. This will create a mysite directory in your current directory.
在命令行界面下,进入到你放置代码的目录中,执行命令django-admin.py startproject mysite。这将在当前目录下创建一个mysite目录。
Mac OS X permissions
If you’re using Mac OS X, you may see the message “permission denied” when you try to run django-admin.py startproject. This is because, on Unix-based systems like OS X, a file must be marked as “executable” before it can be run as a program. To do this, open Terminal.app and navigate (using the cd command) to the directory where django-admin.py is installed, then run the command chmod +x django-admin.py.
Mac OS X权限设置
如果你是用的是Mac OS X操作系统,你在执行上述命令的时候可能会看到“permission denied”的提示信息。这是因为在基于Unix的操作系统中,必须要为文件设置可执行权限才能让文件像程序一样执行。打开终端,切换目录到django-admin.py所在的目录,执行命令chmod +x django-admin.py。
Note
You’ll need to avoid naming projects after built-in Python or Django components. In particular, this means you should avoid using names like django (which will conflict with Django itself) or test (which conflicts with a built-in Python package).
注意
你要避免用Python内置模块或是Django组件来命名项目。这就是说你应该避免使用django(与Django名称冲突)或是test(与Python内置模块冲突)这样的名称。
django-admin.py should be on your system path if you installed Django via python setup.py. If it’s not on your path, you can find it in site-packages/django/bin, where `site-packages` is a directory within your Python installation. Consider symlinking to django-admin.py from some place on your path, such as /usr/local/bin.
如果你是通过python setup.py来安装Django,django-admin.py就应该在你的系统路径下。如果不在的话,你可以在site-packages/django/bin下找到,这里site-packages位于Python的安装路径下。最好在/usr/local/bin下为django-admin.py建立软链接。
Where should this code live?
If your background is in PHP, you’re probably used to putting code under the Web server’s document root (in a place such as /var/www). With Django, you don’t do that. It’s not a good idea to put any of this Python code within your Web server’s document root, because it risks the possibility that people may be able to view your code over the Web. That’s not good for security.
Put your code in some directory outside of the document root, such as /home/mycode.
代码应该放在哪?
如果你有PHP的背景,你很可能习惯把代码放在Web服务器的文档根目录下面(比如/var/www)。使用Django,你不用这么做。把Python代码放在Web服务器的文档根目录下面并不是一个好办法,因为这会增加用户通过Web服务器浏览你的代码的风险。这样对系统安全性不好。把你的代码放在文档根目录之外,比如/home/mycode。
Let’s look at what startproject created:
我们来看看startproject都创建了些什么:
mysite/
__init__.py
manage.py
settings.py
urls.py
These files are:
• __init__.py: An empty file that tells Python that this directory should be considered a Python package. (Read more about packages in the official Python docs if you're a Python beginner.)
• manage.py: A command-line utility that lets you interact with this Django project in various ways. You can read all the details about manage.py in django-admin.py and manage.py.
• settings.py: Settings/configuration for this Django project. Django settings will tell you all about how settings work.
• urls.py: The URL declarations for this Django project; a "table of contents" of your Django-powered site. You can read more about URLs in URL dispatcher.
这些文件是:
__init__.py 一个空文件,它表示当前文件夹要被当做一个Python包来对待。(如果你是Python初学者,关于包的概念请看官方文档)
manage.py 命令行交互工具。你可以在django-admin.py and manage.py找到与manage.py有关的所有细节资料。
settings.py Django项目的配置文件。Django设置会告诉你这个文件是怎样工作的。
urls.py Django项目的URL声明文件。你可以在URL分发器中找到更多的相关内容。
The development server
开发服务器
Let's verify this worked. Change into the mysite directory, if you haven't already, and run the command python manage.py runserver. You'll see the following output on the command line:
我们来看看这能不能正常运行。进入mysite目录,执行命令python manage.py runserver。你能看到如下的输出:
Validating models...
0 errors found.
Django version 1.0, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
You've started the Django development server, a lightweight Web server written 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.
你已经启动了Django开发服务器,一个以Python编写的轻量级Web服务器。我们在Django中包含了这个小玩意是为了让你在发布程序之前,能够不需要配置生产环境的服务器而进行快速开发。
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.)
现在请好好注意:千万别在生产环境上用这个自带的服务器。它只是为开发而使用的。(我们的业务是做Web框架,不是Web服务器。)
Now that the server's running, visit http://127.0.0.1:8000/ with your Web browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel. It worked!
现在服务器正在运行中,访问http://127.0.0.1:8000/。你会看到一个有意思的类似蜡笔画的浅蓝色“Welcome to Django”页面。嗯,它正常运行了!
Changing the port
By default, the runserver command starts the development server on port 8000. If you want to change the server's port, pass it as a command-line argument. For instance, this command starts the server on port 8080:
python manage.py runserver 8080
Full docs for the development server can be found in the runserver reference.
改变端口
默认情况下,runserver让开发服务器通过8000端口进行通信。如果你想改变服务器的端口,把端口号作为命令行参数传入即可。下面的例子就是将服务器端口设置为8080:
python manage.py runserver 8080
有关开发服务器的全部文档,可以在runserver参考中找到。
Database setup
数据库设置
Now, edit settings.py. It's a normal Python module with module-level variables representing Django settings. Change these settings to match your database's connection parameters:
• DATABASE_ENGINE -- Either 'postgresql_psycopg2', 'mysql' or 'sqlite3'. Other backends are also available.
• DATABASE_NAME -- The name of your database. If you're using SQLite, the database will be a file on your computer; in that case, DATABASE_NAME should be the full absolute path, including filename, of that file. If the file doesn't exist, it will automatically be created when you synchronize the database for the first time (see below).
When specifying the path, always use forward slashes, even on Windows (e.g. C:/homes/user/mysite/sqlite3.db).
• DATABASE_USER -- Your database username (not used for SQLite).
• DATABASE_PASSWORD -- Your database password (not used for SQLite).
• DATABASE_HOST -- The host your database is on. Leave this as an empty string if your database server is on the same physical machine (not used for SQLite).
现在编辑settings.py。这是一个Python的模块文件,有很多代表Django设置的模块变量。你可以改变如下的设置来匹配你的数据库连接参数:
DATABASE_ENGINE postgresql_psycopg2、mysql、sqlite3以及其他的数据库类型都可以。
DATABASE_NAME 数据库的名称。如果你使用SQLite,数据库就是一个文件;这种情况下,DATABASE_NAME应当是这个文件的绝对路径。如果文件不存在,在第一次同步数据库的时候会创建这个文件(下面有详细介绍)。
在填写路径的时候,永远都要使用斜杠符号(/),就算是在Windows上也是如此(比如C:/homes/user/mysite/sqlite3.db)。
DATABASE_USER 访问数据库的用户名(SQLite下不使用)。
DATABASE_PASSWORD 访问数据库的密码(SQLite下不使用)。
DATABASE_HOST 数据库所在主机。如果你的数据库在同一台物理机器上这里就可以留空(SQLite下不使用)。
If you're new to databases, we recommend simply using SQLite (by setting DATABASE_ENGINE to 'sqlite3'). SQLite is included as part of Python 2.5 and later, so you won't need to install anything else.
如果你是个数据库新手,我们建议你使用SQLite(设置DATABASE_ENGINE为sqlite3)。SQLite包含在Python2.5及其后续版本中,所以你不用再安装其他的任何东西。
Note
If you're using PostgreSQL or MySQL, make sure you've created a database by this point. Do that with "CREATE DATABASE database_name;" within your database's interactive prompt.
If you're using SQLite, you don't need to create anything beforehand - the database file will be created automatically when it is needed.
注意
如果你使用PostgreSQL或MySQL,请确认你已经创建了一个数据库。在你的数据库命令行下使用命令CREATE DATABASE database_name即可。
如果你使用SQLite,就什么都不用创建了——数据库文件在需要的时候会自动创建。
While you're editing settings.py, take note of the INSTALLED_APPS 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.
在编辑settings.py时,注意一下文件底部的INSTALLED_APPS设置。这个变量保存了在当前Django项目中可用的Django程序的名称。Django程序可以在多个项目中复用,而且你可以把这些程序打包部署以供其他的程序调用。
By default, INSTALLED_APPS contains the following apps, all of which come with Django:
• django.contrib.auth -- An authentication system.
• django.contrib.contenttypes -- A framework for content types.
• django.contrib.sessions -- A session framework.
• django.contrib.sites -- A framework for managing multiple sites with one Django installation.
默认情况下,INSTALLED_APPS包含了以下的App,都是Django自带的:
django.contrib.auth 认证系统
django.contrib.contenttypes content types框架
django.contrib.sessions session框架
django.contrib.sites 使用一个Django项目来管理多个站点的框架
These applications are included by default as a convenience for the common case.
为了方便公用,这些程序都默认包含在配置文件中。
Each of these applications makes use of at least one database table, though, so we need to create the tables in the database before we can use them. To do that, run the following command:
每个程序都至少用到了一个数据表,所以,我们要在数据库中创建对应的数据表。执行下面的命令:
python manage.py syncdb
The syncdb command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your settings.py file. You'll see a message for each database table it creates, and you'll get a prompt asking you if you'd like to create a superuser account for the authentication system. Go ahead and do that.
syncdb命令会查找INSTALLED_APPS设置并根据settings.py文件的数据库设置创建所有必须的数据表。每创建一个数据表的时候你都能看到对应的提示信息,并且系统还会提示你是否为认证系统创建一个超级用户。请按照提示创建超级用户。
If you're interested, run the command-line client for your database and type \dt (PostgreSQL), SHOW TABLES; (MySQL), or .schema (SQLite) to display the tables Django created.
如果你感兴趣,可以进入到数据库命令行内,输入\dt(PostgreSQL)、SHOW TABLES;(MySQL)或者.schema(SQLite)来显示Django创建的数据表。
For the minimalists
Like we said above, the default applications are included for the common case, but not everybody needs them. If you don't need any or all of them, feel free to comment-out or delete the appropriate line(s) from INSTALLED_APPS before running syncdb. The syncdb command will only create tables for apps in INSTALLED_APPS.
为最低要求者所准备
上面说道,默认的程序是为了方便共用包含进来的,但是不是所有人都需要它们。如果你一个都不需要,就在执行syncdb前将INSTALLED_APPS内的这些程序注释掉或者直接删除。syncdb只会为INSTALLED_APPS内的程序创建数据表。
Creating models
创建模型
Now that your environment -- a "project" -- is set up, you're set to start doing work.
现在你的项目环境就已经建立好,可以开始正式的工作了。
Each application you write in Django consists of a Python package, somewhere on your Python path, that follows a certain convention. Django comes with a utility that automatically generates the basic directory structure of an app, so you can focus on writing code rather than creating directories.
你用Django写成的每个程序都是由Python包组成的,这些包位于Python Path中并遵循一定的命名规范。Django有个工具能够自动生成程序的基本目录结构,所以你可以专注与写代码而不用去创建目录。
Projects vs. apps
What's the difference between a project and an app? An app is a Web application that does something -- e.g., a weblog system, a database of public records or a simple poll app. A project is a collection of configuration and apps for a particular Web site. A project can contain multiple apps. An app can be in multiple projects.
项目VS程序
项目(project)和程序(app)之间有什么不同?程序是可以是一个博客系统、公共记录的数据库或非常简单的投票程序。项目是一个网站的配置和程序的集合。项目可以包含多个程序;程序也可以运用到多个项目中去。
In this tutorial, we'll create our poll app in the 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.
在这本新手入门中,为了简便,我们会在mysite目录下创建投票程序。这个程序就会耦合到这个项目中——也就是说,投票程序内的所有Python代码可以用mysite.polls来进行引用。在后面的部分中,我们会讨论怎样在部署的时候将程序进行解耦。
To create your app, make sure you're in the mysite directory and type this command:
要创建程序,请确定你现在位于mysite目录下并输入以下命令:
python manage.py startapp polls
That'll create a directory polls, which is laid out like this:
这样做会创建一个polls目录,结构如下所示:
polls/
__init__.py
models.py
views.py
This directory structure will house the poll application.
这个目录就是投票程序的正式结构。
The first step in writing a database Web app in Django is to define your models -- essentially, your database layout, with additional metadata.
在Django中开发一个有数据库的Web程序的第一步就是定义模型——就是数据库设计以及附加元数据。
Philosophy
A model is the single, definitive source of data about your data. It contains the essential fields and behaviors of the data you're storing. Django follows the DRY Principle. The goal is to define your data model in one place and automatically derive things from it.
哲理
模型是你的数据的单一的、限定的源。它包含你要保存的数据的基本字段和行为。Django遵循DRY原则。目标是为了只在一处地方定义你的数据模型并能够自动从其中获取数据。
In our simple poll app, we'll create two models: polls and choices. A poll has a question and a publication date. A choice has two fields: the text of the choice and a vote tally. Each choice is associated with a poll.
在我们的投票程序中,要创建两个模型:polls(投票)和choices(选项)。投票有问题和发布日期两个字段。选项有两个字段:每个选项的文本内容和投票统计。每个选项都和投票进行关联。
These concepts are represented by simple Python classes. Edit the polls/models.py file so it looks like this:
这些概念都由Python类所表现出来。编辑polls/models.py文件,加入下面的代码:
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
Errors about max_length
If Django gives you an error message saying that max_length is not a valid argument, you're most likely using an old version of Django. (This version of the tutorial is written for the latest development version of Django.) If you're using a Subversion checkout of Django's development version (see the installation docs for more information), you shouldn't have any problems.
If you want to stick with an older version of Django, you'll want to switch to the Django 0.96 tutorial, because this tutorial covers several features that only exist in the Django development version.
关于max_length的错误
如果Django发出错误信息告诉你max_length不是一个有效的参数,那你可能就是在用Django的旧版本。(当前的新手入门是建立在最新的Django版本上的)如果你是从SVN中获取的Django开发版本(详细信息看这里),你就不会有这些问题。
如果你坚持要用Django的旧版本,那你就该参考Django 0.96的新手入门,这篇文章中会包含一些只在Django最新开发版本中包含的特性。
The code is straightforward. Each model is represented by a class that subclasses django.db.models.Model. Each model has a number of class variables, each of which represents a database field in the model.
上面的代码很直接。每个模型都由一个继承自django.db.models.Model的类来描述,都有一定数量的类变量,每个类变量都对应一个数据库字段。
Each field is represented by an instance of a Field class -- e.g., CharField for character fields and DateTimeField for datetimes. This tells Django what type of data each field holds.
每个字段都由一个Field类的实例来进行描述——比如CharField表示字符类型的字段而DateTimeField表示日期时间型的。这会告诉Django数据库字段保存了什么类型的数据。
The name of each Field instance (e.g. question or pub_date ) is the field's name, in machine-friendly format. You'll use this value in your Python code, and your database will use it as the column name.
每个Field实例的名字(例如question或pub_date)就是字段的名字,字段的格式是亲和机器式的。在你的Python代码中会用到这个值,而数据库会将这个值认作表的列名。
You can use an optional first positional argument to a Field to designate a human-readable name. That's used in a couple of introspective parts of Django, and it doubles as documentation. If this field isn't provided, Django will use the machine-readable name. In this 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.
你可以在初始化Field实例时使用第一位置可选参数来指定一个符合人类习惯的名称。这在Django的一些内省部分中被使用到了,而且这个还能作为文档来增强代码的可读性。如果没有提供这个参数,Django会使用符合机器习惯的名称。例如,我们只为Poll.pub_date定义了一个人类名称。对于模型中的其他字段,机器名称就已经足够让人们理解它表示什么含义了。
Some Field classes have required elements. CharField, for example, requires that you give it a max_length. That's used not only in the database schema, but in validation, as we'll soon see.
有些Field类有必要元素。比如CharField,要求你指定max_length。这并不只是用于数据库里,我们以后就会看到它也用在数据验证中。
Finally, note a relationship is defined, using ForeignKey. That tells Django each Choice is related to a single Poll. Django supports all the common database relationships: many-to-ones, many-to-manys and one-to-ones.
最后,注意我们使用ForeignKey定义了一个关系。这会告诉Django每个Choice会同一个Poll进行关联。Django支持所有的通用数据库关系类型:多对一、多对多、一对一。
Activating models
启用模型
That small bit of model code gives Django a lot of information. With it, Django is able to:
• Create a database schema (CREATE TABLE statements) for this app.
• Create a Python database-access API for accessing Poll and Choice objects.
But first we need to tell our project that the polls app is installed.
刚才的一小段有关模型的代码,能够让Django做很多事情。有了这些代码,Django能够:
为程序创建对应的数据表。
给Poll和Choice对象创建数据库访问API。
Philosophy
Django apps are "pluggable": You can use an app in multiple projects, and you can distribute apps, because they don't have to be tied to a given Django installation.
哲理
Django程序是“插入式的”:你可以在多个项目中使用一个程序,你还可以将程序打包分发,因为这些程序不需要被绑定到Django的安装环境中。
Edit the settings.py file again, and change the INSTALLED_APPS setting to include the string 'mysite.polls'. So it'll look like this:
再次编辑settings.py文件,为INSTALLED_APPS加入“mysite.polls”。就像下面所显示的一样:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'mysite.polls'
)
Now Django knows mysite includes the polls app. Let's run another command:
现在Django就知道mysite项目中包含了polls程序了。现在我们执行另一条命令:
python manage.py sql polls
You should see something similar to the following (the CREATE TABLE SQL statements for the polls app):
你应该能够看到类似于下面的输出(polls程序的创建数据表SQL):
BEGIN;
CREATE TABLE "polls_poll" (
"id" serial NOT NULL PRIMARY KEY,
"question" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
"choice" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
COMMIT;
Note the following:
• The exact output will vary depending on the database you are using.
• Table names are automatically generated by combining the name of the app (polls) and the lowercase name of the model -- poll and choice. (You can override this behavior.)
• Primary keys (IDs) are added automatically. (You can override this, too.)
• By convention, Django appends "_id" to the foreign key field name. Yes, you can override this, as well.
• The foreign key relationship is made explicit by a REFERENCES statement.
• It's tailored to the database you're using, so database-specific field types such as auto_increment (MySQL), serial (PostgreSQL), or integer primary key (SQLite) are handled for you automatically. Same goes for quoting of field names -- e.g., using double quotes or single 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.
注意以下几点:
真实的输出会根据你所使用的数据库有所不同。
数据表的名字由程序的名字(polls)和模型的小写名字(poll和choice)组成(你可以重写这个行为)。
主键(ID)是自动添加的(这个你也可以重写)。
根据命名规范,Django会给外键字段加上“_id”,你还是可以重写这个行为。
外键关系由REFERENCES语句显式声明。
生成的语句对你所用的数据库都是自适应的,所以类似于auto_increment(MySQL)、serial(PostgreSQL)或integer primary key(SQLite)的数据库字段都会自动进行处理。在引用字段名称的时候也是自适应的——会使用双引号或单引号。本文的作者使用的是PostgreSQL数据库,所以例子中输出的是PostgreSQL语法。
输出的SQL语句并不会在数据库内执行——它只是打印出来让你了解Django认为什么样的SQL是必须的。如果你要执行,之需要复制粘贴到数据库命令行下就可以了。但是,我们等会就能看到,Django有更简单的方法来执行SQL。
If you're interested, also run the following commands:
• python manage.py validate -- Checks for any errors in the construction of your models.
• python manage.py sqlcustom polls -- Outputs any custom SQL statements (such as table modifications or constraints) that are defined for the application.
• python manage.py sqlclear polls -- Outputs the necessary DROP TABLE statements for this app, according to which tables already exist in your database (if any).
• python manage.py sqlindexes polls -- Outputs the CREATE INDEX statements for this app.
• python manage.py sqlall polls -- A combination of all the SQL from the sql, sqlcustom, and sqlindexes commands.
如果你有兴趣,也可以执行以下命令:
python manage.py validate 检测在生成模型的时候是否有错误。
python manage.py sqlcustom polls 输出程序中定义的custom SQL语句(比如表或约束的修改)。
python manage.py sqlclear polls 根据有哪些表存在于数据库中,输出必要的DROP TABLE语句。
python manage.py sqlindexes polls 输出CREATE INDEX语句。
python manage.py sqlall polls 组合输出sql、sqlcustom和sqlindexes的结果。
Looking at the output of those commands can help you understand what's actually happening under the hood.
这些命令的输出结果能够帮助你理解在程序底层到底做了什么处理。
Now, run syncdb again to create those model tables in your database:
现在,再次执行syncdb命令来创建模型对应的数据表:
python manage.py syncdb
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.
syncdb命令会给INSTALLED_APPS中在数据库里没有对应数据表的程序执行sqlall操作。这个操作根据你上一次执行syncdb的结果,为项目中所有的程序创建对应的表、初始化数据并创建索引。syncdb你想调用多少次就能调用多少次,而它只会创建数据库里还不存在的表。
Read the django-admin.py documentation for full information on what the manage.py utility can do.
想了解manage.py工具更多的功能,请阅读django-admin.py的文档。
Playing with the API
使用模型API
Now, let's hop into the interactive Python shell and play around with the free API Django gives you. To invoke the Python shell, use this command:
现在,进入到Python的命令行环境中,开始使用Django提供的API吧。要进入命令行,输入下面的命令:
python manage.py shell
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 Django refer to projects in Python dotted-path notation (e.g. 'mysite.polls.models'). In order for this to work, the mysite package has to be on sys.path.
We've already seen one example of this: the INSTALLED_APPS setting is a list of packages in dotted-path notation.
• Setting the DJANGO_SETTINGS_MODULE environment variable, which gives Django the path to your settings.py file.
我们没有直接使用python命令进入命令行,因为manage.py会为你配置项目环境。配置环境包括以下两点:
• 在sys.path中加入mysite。便捷起见,项目中所引用的模块都是以Python的“点路径”的方式来表示(比如“mysite.polls.models”)。为了正常工作,mysite包就必须在sys.path内。
我们已经看到了一个例子:INSTALLED_APPS就是一组用“点路径”方式表示的包的集合。
• 设置DJANGO_SETTINGS_MODULE环境变量,这个变量会将settings.py的路径告诉Django。
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.
For more information on all of this, see the django-admin.py documentation.
忽略manage.py
如果你不想用manage.py,没问题,只要确定mysite在Python路径的根级别下然后给mysite.settings设置DJANGO_SETTINGS_MODULE环境变量。
要了解更多的内容,请参考django-admin.py文档。
Once you're in the shell, explore the database API:
进入命令行后,请浏览Django数据库API:
>>> from mysite.polls.models import Poll, Choice # Import the model classes we just wrote.
# No polls are in the system yet.
>>> Poll.objects.all()
[]
# Create a new Poll.
>>> import datetime
>>> p = Poll(question="What's up?", pub_date=datetime.datetime.now())
# Save the object into the database. You have to call save() explicitly.
>>> p.save()
# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> p.id
1
# Access database columns via Python attributes.
>>> p.question
"What's up?"
>>> p.pub_date
datetime.datetime(2007, 7, 15, 12, 00, 53)
# Change values by changing the attributes, then calling save().
>>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0)
>>> p.save()
# objects.all() displays all the polls in the database.
>>> Poll.objects.all()
[<Poll: Poll object>]
Wait a minute. <Poll: Poll object> is, utterly, an unhelpful representation of this object. Let's fix that by editing the polls model (in the polls/models.py file) and adding a __unicode__() method to both Poll and Choice:
慢着,<Poll: Poll object>这样的形式绝对不是一个直白的表达方式。我们可以修改模型的代码(在polls/models.py文件里),给Poll和Choice各加入一个__unicode__()方法来解决这个问题:
class Poll(models.Model):
# ...
def __unicode__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
return self.choice
If __unicode__() doesn't seem to work
If you add the __unicode__() method to your models and don't see any change in how they're represented, you're most likely using an old version of Django. (This version of the tutorial is written for the latest development version of Django.) If you're using a Subversion checkout of Django's development version (see the installation docs for more information), you shouldn't have any problems.
If you want to stick with an older version of Django, you'll want to switch to the Django 0.96 tutorial, because this tutorial covers several features that only exist in the Django development version.
如果__unicode__()看起来好像没用
如果在模型中加入了__unicode__()方法,但是在命令行里对象的表现方式又没有任何改变,那你可能就是在用旧版本的Django。(当前的新手入门是建立在最新的Django版本上的)如果你是从SVN中获取的Django开发版本(详细信息看这里),你就不会有这些问题。
如果你坚持要用Django的旧版本,那你就该参考Django 0.96的新手入门,这篇文章中会包含一些只在Django最新开发版本中包含的特性。
It's important to add __unicode__() methods to your models, not only for your own sanity when dealing with the interactive prompt, but also because objects' representations are used throughout Django's automatically-generated admin.
给模型加上__unicode__()方法是很重要的,不光是为了在命令行里能够让你保持思路清晰,而且在Django自动生成的管理界面里对象表现也是会被用到的。
Why __unicode__() and not django.db.models.Model.__str__()?
If you're familiar with Python, you might be in the habit of adding django.db.models.Model.__str__() methods to your classes, not __unicode__() methods. We use __unicode__() here because Django models deal with Unicode by default. All data stored in your database is converted to Unicode when it's returned.
Django models have a default django.db.models.Model.__str__() method that calls __unicode__() and converts the result to a UTF-8 bytestring. This means that unicode(p) will return a Unicode string, and str(p) will return a normal string, with characters encoded as UTF-8.
If all of this is jibberish to you, just remember to add __unicode__() methods to your models. With any luck, things should Just Work for you.
为什么是__unicode__()而不是django.db.model.Model.__str__()?
如果你熟悉Python,你可能会有在模型类里使用django.db.model.Model.__str__()方法的习惯而不会去使用__unicode__()。我们用__unicode__()方式是因为Django模型默认处理Unicode数据。当数据库里的数据返回时,它们全都会被转成Unicode编码。
Django模型有个默认的django.db.model.Model.__str__()方法来调用__unicode__()方法并将结果转换成UTF8格式。这意味着unicode(p)会返回Unicode字符串,而str(p)会返回一个UTF8编码的普通字符串
如果这些东西让你很困扰,那就只需要记住给模型类加入__unicode__()方法。幸运的话,这些代码会正常工作。
Note these are normal Python methods. Let's add a custom method, just for demonstration:
上面提到的都是Python的魔术方法。现在我们加上一个自定义方法做演示:
import datetime
# ...
class Poll(models.Model):
# ...
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
Note the addition of import datetime to reference Python's standard datetime module.
请注意增加了import datetime部分是为了引用Python的标准日期时间模块。
Let's jump back into the Python interactive shell by running python manage.py shell again:
我们再次运行python manage.py shell回到命令行下:
>>> from mysite.polls.models import Poll, Choice
# Make sure our __unicode__() addition worked.
>>> Poll.objects.all()
[<Poll: What's up?>]
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]
# Get the poll whose year is 2007. Of course, if you're going through this
# tutorial in another year, change as appropriate.
>>> Poll.objects.get(pub_date__year=2007)
<Poll: What's up?>
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Poll matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What's up?>
# Make sure our custom method worked.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_today()
False
# 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.create(choice='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice='Just hacking again', votes=0)
# Choice objects have API access to their related Poll objects.
>>> c.poll
<Poll: What's up?>
# And vice versa: Poll objects get access to Choice objects.
>>> p.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any poll whose pub_date is in 2007.
>>> Choice.objects.filter(poll__pub_date__year=2007)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
# Let's delete one of the choices. Use delete() for that.
>>> c = p.choice_set.filter(choice__startswith='Just hacking')
>>> c.delete()
For full details on the database API, see our Database API reference.
要了解更多的数据库API只是,请查阅Database API reference。
When you're comfortable with the API, read part 2 of this tutorial to get Django's automatic admin working.
当你对API有所了解之后,可以开始第二部分来学习Django自动生成后台是怎样工作的。
2 楼 bluky999 2010-07-05 15:55
有想法,啥时候review完了整理出来啊?
1 楼 image72 2010-06-27 06:26