Django 1.10中文文檔:第一個應(yīng)用 part 2

已經(jīng)同步到gitbook,想閱讀的請轉(zhuǎn)到gitbook: Django 1.10 中文文檔

This tutorial begins where Tutorial 1 left off. We’ll setup the database, create your first model, and get a quick introduction to Django’s automatically-generated admin site.

緊接著教程第一部分,我們開始配置數(shù)據(jù)庫,創(chuàng)建你的第一個model,并且快速了解下Django的后臺管理系統(tǒng)

Database setup

Now, open up mysite/settings.py. It’s a normal Python module with module-level variables representing Django settings.

現(xiàn)在,打開 mysite/settings.py. 這是一個普通的python模塊包,包含了Django配置的模塊級變量。

By default, the configuration uses SQLite. If you’re new to databases, or you’re just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won’t need to install anything else to support your database. When starting your first real project, however, you may want to use a more scalable database like PostgreSQL, to avoid database-switching headaches down the road.

默認情況下,Django使用的是SQLite數(shù)據(jù)庫。如果你是數(shù)據(jù)庫菜鳥或者你僅僅想試用一下Django,這是最簡單的選擇了。python自帶了SQLite模塊,所以你不需要安裝任何東西。然后當你真正想寫一個項目時,你可能需要用到功能更豐富的數(shù)據(jù)庫,比如說PostgreSQL,避免后面面臨數(shù)據(jù)庫切換的頭疼問題。

If you wish to use another database, install the appropriate database bindings and change the following keys in theDATABASES 'default' item to match your database connection settings:

如果你想用其他的數(shù)據(jù)庫,請先安裝好相應(yīng)的數(shù)據(jù)庫軟件 ,并修改settings文件中DATABASES 'default' 選項,用于連接你的數(shù)據(jù)庫:

  • ENGINE – Either 'django.db.backends.sqlite3'
    , 'django.db.backends.postgresql','django.db.backends.mysql', or 'django.db.backends.oracle'. Other backends are also available.

  • 可以是’django.db.backends.sqlite3’或者’django.db.backends.postgresql’,’django.db.backends.mysql’, or ’django.db.backends.oracle’,當然 其它可用的也行。

  • NAME – The name of your database. If you’re using SQLite, the database will be a file on your computer; in that case, NAME should be the full absolute path, including filename, of that file. The default value, os.path.join(BASE_DIR, 'db.sqlite3'), will store the file in your project directory.

  • 數(shù)據(jù)庫的名字。如果你使用的是默認的SQLite,那么數(shù)據(jù)庫將作為一個文件將存放在你的本地機器內(nèi),NAME應(yīng)該是這個文件的完整絕對路徑,包括文件名。設(shè)置中的默認值os.path.join(BASE_DIR, ’db.sqlite3’),將把該文件儲存在你的項目目錄下。

If you are not using SQLite as your database, additional settings such as USER, PASSWORD, and HOST must be added. For more details, see the reference documentation for DATABASES.

如果你不是用SQLite,那你需要配置其他的設(shè)置,如USER, PASSWORD, and HOST 都是必需的. 詳細請看DATABASES相關(guān).

For databases other than SQLite
If you’re using a database besides SQLite, make sure you’ve created a database by this point. Do that with “CREATE DATABASE database_name;” within your database’s interactive prompt.
Also make sure that the database user provided in mysite/settings.py
has “create database” privileges. This allows automatic creation of a test database which will be needed in a later tutorial.
If you’re using SQLite, you don’t need to create anything beforehand - the database file will be created automatically when it is needed.

**SQLite外的其他數(shù)據(jù)庫
在使用非SQLite的數(shù)據(jù)庫時,請務(wù)必首先在數(shù)據(jù)庫提示符交互模式下創(chuàng)建數(shù)據(jù)庫,你可以使用命令:“CREATE DATABASE database_name;”
確保你在settings文件中提供的數(shù)據(jù)庫用戶具有創(chuàng)建數(shù)據(jù)庫表的權(quán)限,因為在接下來的教程中,我們需要自動創(chuàng)建一個test數(shù)據(jù)庫。
如果你使用的是SQLite,那么你無需做任何預先配置,數(shù)據(jù)庫文件會自動創(chuàng)建

While you’re editing mysite/settings.py, set TIME_ZONE to your time zone.

Also, note the INSTALLED_APPS setting at the top of the file. That 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:

  • django.contrib.admin – The admin site. You’ll use it shortly.
  • django.contrib.auth – An authentication system.
  • django.contrib.contenttypes – A framework for content types.
  • django.contrib.sessions – A session framework.
  • django.contrib.messages – A messaging framework.
  • django.contrib.staticfiles – A framework for managing static files.

These applications are included by default as a convenience for the common case.

Some of these applications make 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:

在修改settings文件時,請順便將TIME_ZONE設(shè)置為你所在的時區(qū)。

同時,請注意settings文件中頂部的INSTALLED_APPS設(shè)置項。它保存了所有的在當前項目中被激活的Django應(yīng)用。你必須將你自定義的app注冊在這里。每個應(yīng)用可以被多個項目使用,而且你可以打包和分發(fā)給其他人在他們的項目中使用。

默認情況,INSTALLED_APPS中包含以下應(yīng)用,它們都是Django自帶的:

  • django.contrib.admin:admin站點
  • django.contrib.auth:身份認證系統(tǒng)
  • django.contrib.contenttypes:內(nèi)容類型框架
  • django.contrib.sessions:會話框架
  • django.contrib.messages:消息框架
  • django.contrib.staticfiles:靜態(tài)文件管理框架

以上應(yīng)用默認會包含,對于大多數(shù)項目都是需要的

上面的每個應(yīng)用都至少需要使用一個數(shù)據(jù)庫表,所以在使用它們之前我們需要在數(shù)據(jù)庫中創(chuàng)建這些表。使用這個命令:

python manage.py migrate

The migrate command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your mysite/settings.py file and the database migrations shipped with the app (we’ll cover those later). You’ll see a message for each migration it applies. If you’re interested, run the command-line client for your database and type \dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite), or SELECT TABLE_NAME FROM USER_TABLES; (Oracle) to display the tables Django created.

migrate命令將根據(jù)INSTALLED_APPS、mysite/settings.py的數(shù)據(jù)庫設(shè)置以及app的數(shù)據(jù)庫遷移(稍后會講到)信息創(chuàng)建相關(guān)的表 ,你講看到每一個數(shù)據(jù)庫消息的信息。如果你感興趣,可以在你的數(shù)據(jù)庫命令行下輸入:\dt (PostgreSQL), SHOW TABLES; (MySQL), 或 .schema (SQLite), 或SELECT TABLE_NAME FROM USER_TABLES; (Oracle) 來列出 Django 所創(chuàng)建的表。

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 migrate. The migrate command will only run migrations for apps in INSTALLED_APPS.

就像我們上面說的,默認情況下會自帶那些公共應(yīng)用。如果你不需要其中一個或所有的,你可以在migrate前,將INSTALLED_APPS內(nèi)注釋掉或者刪除對應(yīng)的行。 migrate命令只會針對INSTALL_APPS進行操作

Creating models

Now we’ll define your models – essentially, your database layout, with additional metadata.

Philosophy

A model is the single, definitive source of truth 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.

This includes the migrations - unlike in Ruby On Rails, for example, migrations are entirely derived from your models file, and are essentially just a history that Django can roll through to update your database schema to match your current models.

創(chuàng)建models

現(xiàn)在我們開始定義models - 本質(zhì)上,就是你的數(shù)據(jù)庫結(jié)構(gòu),和其他的一些元數(shù)據(jù)信息

Philosophy

model就是你唯一可信的真實數(shù)據(jù)源。它包含了你所要存儲數(shù)據(jù)的必須字段和行為信息。Django遵循DRY Principle,目的是讓你可以在一個地方定義你的數(shù)據(jù)模型,并以它來驅(qū)動整個項目

關(guān)于migrations - 它不像ruby的Rails,比如說,migrations純靠你的models來驅(qū)動。本質(zhì)上是根據(jù)當前models來更新數(shù)據(jù)庫表的一個歷史記錄。

In our simple poll app, we’ll create two models: Question and Choice. A Question 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 Question.

These concepts are represented by simple Python classes. Edit the polls/models.py file so it looks like this:

在我們的投票應(yīng)用中,我們將創(chuàng)建兩個模型:Question and Choice。Question表包含問題和發(fā)布日期兩個字段。Choice表有兩個字段:選擇文本和投票計數(shù)。每一條choice都關(guān)聯(lián)到一條Question

這些概念都由python的類來定義。編輯polls/models.py,如下

polls/models.py

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

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.

以上代碼簡單明了。每一個model都由一個類來定義,該類是django.db.models.Model的子類。每個類都由數(shù)個變量組成,分別對應(yīng)了數(shù)據(jù)庫里的字段

Each field is represented by an instance of a Field class – e.g., CharFieldfor character fields and DateTimeField for datetimes. This tells Django what type of data each field holds.

每一個字段都是Field 類的實例 -- 如 CharField是字符串字段,DateTimeField是時間字段。這告訴Django每個字段用來存儲什么類型的數(shù)據(jù)

The name of each Field instance (e.g. question_text 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_text 或 pub_date)就是字段的名字名,一個機器友好型的名字。在代碼里你會用到它,而數(shù)據(jù)庫里用它來作字段名。

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 Question.pub_date. For all other fields in this model, the field’s machine-readable name will suffice as its human-readable name.

每個Filed里的第一個可選參數(shù),用來指定一個可讀性好的名字。這在Django的一些內(nèi)部機制中有所用處,也可以兼做文檔。如果沒有指定這個字段,Django會默認使用機器可讀的名字。在這個例子中,我們只為pub_data定義了友好的名字。model的其他字段已經(jīng)通俗易懂。

Some Field classes have required arguments. 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.

有一些字段有必選參數(shù)。例如,CharField要求你給它一個max_length。這個參數(shù)不僅用于數(shù)據(jù)庫模式,而且數(shù)據(jù)驗證中也會用到,我們稍后會看到。

A Field can also have various optional arguments; in this case, we’ve set the default value of votes to 0.

Field 還具有各種可選參數(shù)。在這個例子中,我們設(shè)置votes字段的 默認值 為0。

Finally, note a relationship is defined, using ForeignKey. That tells Django each Choice is related to a single Question. Django supports all the common database relationships: many-to-one, many-to-many, and one-to-one.

最后,注意我們使用ForeignKey定義了一個關(guān)聯(lián)。它告訴Django每個Choice都只關(guān)聯(lián)一個Question。Django支持所有常見的數(shù)據(jù)庫關(guān)聯(lián):多對一、多對多和一對一。

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 Question
    and Choice objects.

But first we need to tell our project that the polls app is installed.

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.

這簡短的model代碼給了Django許多信息。有了它,Django就可以:

  • 為該應(yīng)用創(chuàng)建數(shù)據(jù)庫表(CREATE TABLE 語句)。
  • 為Question對象和Choice對象創(chuàng)建一個訪問數(shù)據(jù)庫的python API。

但是,我們首先得告訴項目:polls應(yīng)用已經(jīng)安裝。

理念

Django 應(yīng)用是可以“插件化”的,即可以在多個項目中使用同一個應(yīng)用,也可以分發(fā)這些應(yīng)用, 因為它們不需要與某個特定的Django安裝綁定。

To include the app in our project, we need to add a reference to its configuration class in the INSTALLED_APPSsetting. The PollsConfig class is in the polls/apps.py file, so its dotted path is 'polls.apps.PollsConfig'
. Edit the mysite/settings.py file and add that dotted path to the INSTALLED_APPS setting. It’ll look like this:

為了安裝應(yīng)用,我們需要在配置中的INSTALLED_APPS中增加相關(guān)設(shè)置。PollsConfig 類就是polls/apps.py文件,以點分割的路徑就是'polls.apps.PollsConfig',編輯mysite/settings.py文件,INSTALLED_APPS配置中增加點分隔符路徑,文件看起來應(yīng)該像這樣:

mysite/settings.py

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Now Django knows to include the polls app. Let’s run another command:

現(xiàn)在Django就知道要安裝polls應(yīng)用了。我們輸入以下命令:

python manage.py makemigrations polls

You should see something similar to the following:

你可以看到類似以下的輸出:

Migrations for 'polls':
  polls/migrations/0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice

By running makemigrations, you’re telling Django that you’ve made some changes to your models (in this case, you’ve made new ones) and that you’d like the changes to be stored as a migration.

運行makemigrations,告訴Django你已經(jīng)對你的models做了一些修改(在本例中,你創(chuàng)建了新的model類),這些修改會作為migration記錄來存儲

Migrations are how Django stores changes to your models (and thus your database schema) - they’re just files on disk. You can read the migration for your new model if you like; it’s the filepolls/migrations/0001_initial.py. Don’t worry, you’re not expected to read them every time Django makes one, but they’re designed to be human-editable in case you want to manually tweak how Django changes things.

Migrations就是Django存儲的models的修改記錄(也就是你的數(shù)據(jù)庫表格)--在磁盤上他們僅僅是文件而已。如果你想,你可以閱讀那些為新模型建立的遷移文件,該文件是filepolls/migrations/0001_initial.py。別擔心,在Django生成遷移文件后,你不必每次都去閱讀,這些文件是可編輯的,以便你手動修改一下Django的操作行為。

There’s a command that will run the migrations for you and manage your database schema automatically - that’s called migrate
, and we’ll come to it in a moment - but first, let’s see what SQL that migration would run. Thesqlmigrate command takes migration names and returns their SQL:

有一個命令可以運行這些migrations文件并自動管理你的數(shù)據(jù)庫表 -- 它是migrate,我們待會兒會用到它 -- 但首先我們看一下,那些遷移會執(zhí)行哪些sql語句。sqlmigrate 命令接收遷移文件信息,并返回sql語句:

python manage.py sqlmigrate polls 0001

You should see something similar to the following (we’ve reformatted it for readability):

你應(yīng)該看到如下內(nèi)容(為了好看我們重新排了下格式):

BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;

COMMIT;

Note the following:

  • The exact output will vary depending on the database you are using. The example above is generated for PostgreSQL.

  • Table names are automatically generated by combining the name of the app (polls) and the lowercase name of the model – question 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 FOREIGN KEY constraint. Don’t worry about the DEFERRABLE parts; that’s just telling PostgreSQL to not enforce the foreign key until the end of the transaction.

  • 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 autoincrement (SQLite) are handled for you automatically. Same goes for the quoting of field names – e.g., using double quotes or single quotes.

  • The sqlmigrate command doesn’t actually run the migration on your database - it just prints it to the screen so that you can see what SQL Django thinks is required. It’s useful for checking what Django is going to do or if you have database administrators who require SQL scripts for changes.

請注意以下幾點:

輸出的具體內(nèi)容會依據(jù)你使用的數(shù)據(jù)庫而不同。 以上例子使用的數(shù)據(jù)庫是PostgreSQL。

表名是自動生成的,由app的名字(polls)和模型名字的小寫字母組合而成 —— question和choice。(你可以重寫這個行為。)

主鍵(IDs)是自動添加的。 (你也可以重寫這個行為。)

按照慣例,Django會在外鍵的字段名后面添加 "_id"。(是的,你依然可以重寫這個行為。)

外鍵關(guān)系由FOREIGN KEY約束顯式聲明。不用在意DEFERRABLE
部分;它只是告訴PostgreSQL直到事務(wù)的最后再執(zhí)行外鍵關(guān)聯(lián)。

這些SQL語句是針對你所使用的數(shù)據(jù)庫定制的,所以會為你自動處理某些數(shù)據(jù)庫所特有的字段例如auto_increment(MySQL)、 serial (PostgreSQL)或integer primary key autoincrement (SQLite) 。在處理字段名的引號時也是如此 —— 例如,使用雙引號還是單引號。

sqlmigrate命令并不會在你的數(shù)據(jù)庫上真正運行遷移文件 —— 它只是把Django 認為需要的SQL打印在屏幕上以讓你能夠看到。
這對于檢查Django將要進行的數(shù)據(jù)庫操作或者你的數(shù)據(jù)庫管理員需要這些SQL腳本是非常有用的。

If you’re interested, you can also run python manage.py check
; this checks for any problems in your project without making migrations or touching the database.

Now, run migrate again to create those model tables in your database:

如果有興趣,你還可以運行 python manage.py check
;它會檢查你的項目中的模型是否存在問題,而不用執(zhí)行遷移或者操作數(shù)據(jù)庫。

現(xiàn)在,再次運行 migrate以在你的數(shù)據(jù)庫中創(chuàng)建模型所對應(yīng)的表:

python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK

The migrate command takes all the migrations that haven’t been applied (Django tracks which ones are applied using a special table in your database called django_migrations) and runs them against your database - essentially, synchronizing the changes you made to your models with the schema in the database.

migrate 命令將找到所有尚未被應(yīng)用的遷移文件(django_migrations的特殊表來追蹤哪些遷移文件已經(jīng)被應(yīng)用過),并且在你的數(shù)據(jù)庫上運行它們 —— 本質(zhì)上來講,就是使你的數(shù)據(jù)庫模式和你改動后的模型進行同步。)

Migrations are very powerful and let you change your models over time, as you develop your project, without the need to delete your database or tables and make new ones - it specializes in upgrading your database live, without losing data. We’ll cover them in more depth in a later part of the tutorial, but for now, remember the three-step guide to making model changes:

遷移功能非常強大,在你開發(fā)項目的過程中,使你在更改models后,無需刪除數(shù)據(jù)庫或表,然后再重建新的。它專注于熱升級你的數(shù)據(jù)庫且不丟數(shù)據(jù)。我們將在本教程的后續(xù)章節(jié)中詳細介紹,但是現(xiàn)在,請記住模型變更的三個基本步驟:

The reason that there are separate commands to make and apply migrations is because you’ll commit migrations to your version control system and ship them with your app; they not only make your development easier, they’re also useable by other developers and in production.

將生成和應(yīng)用遷移文件分開,是因為你可能需要將遷移文件提交到你的版本控制器并跟隨你的應(yīng)用。這樣做不僅使開發(fā)變得更加簡單,而且對其他開發(fā)者以及線上環(huán)境非常有用。

Read the django-admin documentation for full information on what the manage.py utility can do.

閱讀django-admin documentation 來詳細了解manage.py工具所能做的事情。

Playing with the 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:

現(xiàn)在,我們切換到python shell的交互模式,感受一下Django給的API。用如下命令來調(diào)出python shell

python manage.py shell

We’re using this instead of simply typing “python”, because manage.py
sets the DJANGO_SETTINGS_MODULE environment variable, which gives Django the Python import path to your mysite/settings.py file.

我們替代使用簡單的python命令進入python shell,是因為manage.py設(shè)置了DJANGO_SETTINGS_MODULE環(huán)境變量,它告訴Django導入了mysite/settings.py模塊

** Bypassing manage.py**

If you’d rather not use manage.py, no problem. Just set the DJANGO_SETTINGS_MODULE environment variable to mysite.settings, start a plain Python shell, and set up Django:

>> import django
>> django.setup()

> If this raises an [AttributeError
](https://docs.python.org/3/library/exceptions.html#AttributeError), you’re probably using a version of Django that doesn’t match this tutorial version. You’ll want to either switch to the older tutorial or the newer Django version.

> You must run python from the same directory manage.py
 is in, or ensure that directory is on the Python path, so that import mysite works.

> For more information on all of this, see the [django-admin documentation](https://docs.djangoproject.com/en/1.10/ref/django-admin/).

> ** 跳過manage.py**

>  如果你不想使用manage.py,沒問題,只需設(shè)置 [DJANGO_SETTINGS_MODULE](https://docs.djangoproject.com/en/1.10/topics/settings/#envvar-DJANGO_SETTINGS_MODULE)  變量為 mysite.settings,啟動一個普通的 Python shell, 然后設(shè)置Django:

> ```
>>> import os
>>>#設(shè)置DJANGO_SETTINGS_MODULE環(huán)境變量
>>> os.environ['DJANGO_SETTINGS_MODULE']='mysite.settings'
>>> import django
>>> django.setup()

如果你引發(fā)了AttributeError,那你使用的Django版本可能與本教程的版本不符,你可以切換到舊教程,或安裝更新的版本。

你應(yīng)該在 manage.py同級目錄敲python命令,或者確保該目錄在python path內(nèi),這樣你就可以import mysite了

更多詳細信息,請看 django-admin documentation.

Once you’re in the shell, explore the database API:

一旦你進入了這個python shell,那就探索 database API吧:

>>> from polls.models import Question, Choice   # Import the model classes we just wrote.

# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>

# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# Save the object into the database. You have to call save() explicitly.
>>> q.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.
>>> q.id
1

# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()

# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object>]>

Wait a minute. <Question: Question object> is, utterly, an unhelpful representation of this object. Let’s fix that by editing the Question
model (in the polls/models.py file) and adding a str() method to both Question
and Choice:

等會,<Question: Question object> 是什么鬼,這是很不友好的對象表示方法。我們可以修復這個問題,編輯Question model (in the polls/models.py file),在 Question and Choice類增加 str() 方法:

polls/models.py

from django.db import models
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible  # 僅當你需要兼容python2版本的時候
class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

@python_2_unicode_compatible  # only if you need to support Python 2
class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text

It’s important to add str() methods to your models, not only for your own convenience when dealing with the interactive prompt, but also because objects’ representations are used throughout Django’s automatically-generated admin.

給你的模型類添加str() 方法很重要,不僅會使你自己在使用交互式命令行時看得更加方便,而且會在Django自動生成的管理界面中使用對象的這種表示。

Note these are normal Python methods. Let’s add a custom method, just for demonstration:

這是非常普通的Python方法。讓我們來演示一下如何添加自定義方法:

polls/models.py

import datetime

from django.db import models
from django.utils import timezone


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

Note the addition of import datetime and from django.utils import timezone, to reference Python’s standard datetime module and Django’s time-zone-related utilities in django.utils.timezone, respectively. If you aren’t familiar with time zone handling in Python, you can learn more in the time zone support docs.

Save these changes and start a new Python interactive shell by running python manage.py shell again:

注意import datetime 和from django.utils import timezone分別引用Python 的標準datetime 模塊和Djangodjango.utils.timezone
中時區(qū)相關(guān)的工具。如果你不了解Python中時區(qū)的處理方法,你可以在時區(qū)相關(guān)文檔中了解更多的知識。

保存這些改動,然后通過python manage.py shell再次打開一個新的Python 交互式shell:

>>> from polls.models import Question, Choice

# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question 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 Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question 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. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.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 question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

For more information on model relations, see Accessing related objects. For more on how to use double underscores to perform field lookups via the API, see Field lookups. For full details on the database API, see our Database API reference.

更多關(guān)于模型相關(guān)的信息,請查看Accessing related objects。更多關(guān)于如何在這些API中使用雙下劃線來執(zhí)行字段查詢的信息,請查看 字段查詢。想了解所有數(shù)據(jù)庫API的信息,請查看我們的 數(shù)據(jù)庫API參考.

Introducing the Django Admin

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.

為你的團隊或客戶編寫增刪改查的admin管理系統(tǒng)是非常乏味的,也沒有多少創(chuàng)造性價值。基于這考慮,Django自動的為你的models創(chuàng)建了管理接口。

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.

Django最初是為新聞?wù)军c開發(fā)的,新聞發(fā)布者和公共站點界限明顯。管理員通過這個系統(tǒng)添加新聞、時間、體育賽事等,這些信息展示在公共網(wǎng)站上。Django提供了一個統(tǒng)一接口給站點管理員來編輯內(nèi)容。

The admin isn’t intended to be used by site visitors. It’s for site managers.

admin系統(tǒng)并不是為了訪客設(shè)計的,只對站點管理員開放。

Creating an admin user

First we’ll need to create a user who can login to the admin site. Run the following command:

python manage.py createsuperuser

Enter your desired username and press enter.

Username: admin

You will then be prompted for your desired email address:

Email address: admin@example.com

The final step is to enter your password. You will be asked to enter your password twice, the second time as a confirmation of the first.

Password: **********
Password (again): *********
Superuser created successfully.

創(chuàng)建管理員

首先我們需要創(chuàng)建一個能登錄admin站點的用戶,運行以下命令:

python manage.py createsuperuser

輸入你喜歡的名字,按下回車.

Username: admin

然后會提示輸入你的郵箱:

Email address: admin@example.com

最后一步是輸入密碼。你需要輸入兩次,第二次作為第一次的進一步確認:

Password: **********
Password (again): *********
Superuser created successfully.

Start the development server

The Django admin site is activated by default. Let’s start the development server and explore it.

If the server is not running start it like so:

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:

啟動開發(fā)服務(wù)器

Django的admin站點默認是激活的。讓我們開啟開發(fā)服務(wù)器來探索一下:

如果服務(wù)器沒開啟,用下面的方法來啟動:

python manage.py runserver

現(xiàn)在,打開web瀏覽器,本地域名訪問“/admin/” -- 比如說http://127.0.0.1:8000/admin/。你可以看到admin的登錄界面:

Paste_Image.png

Since translation is turned on by default, the login screen may be displayed in your own language, depending on your browser’s settings and if Django has a translation for this language.

translation 默認是開啟的,登錄界面顯示的應(yīng)該是你的母語,這取決于你的瀏覽器設(shè)置,如果Django有這種翻譯版本的話。

Enter the admin site

Now, try logging in with the superuser account you created in the previous step. You should see the Django admin index page:

現(xiàn)在,你可以用你剛剛創(chuàng)建的超級用戶來登錄了。登錄后你應(yīng)該可以看到如下index頁面:

Django admin index page

You should see a few types of editable content: groups and users. They are provided by django.contrib.auth, the authentication framework shipped by Django.

當前已經(jīng)有兩個可編輯的內(nèi)容:groups和users。它們是 django.contrib.auth模塊提供的身份認證框架。

Make the poll app modifiable in the admin

在admin中注冊投票應(yīng)用

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 Question
objects have an admin interface. To do this, open the polls/admin.py
file, and edit it to look like this:

但是我們創(chuàng)建的投票應(yīng)用哪去了呢?它并沒有在admin的首頁里。我們還有一件事要做:告訴admin站點Question要有admin系統(tǒng)。編輯polls/admin.py文件,代碼如下:

polls/admin.py

from django.contrib import admin

from .models import Question

admin.site.register(Question)

Explore the free admin functionality

Now that we’ve registered Question, Django knows that it should be displayed on the admin index page:

Question注冊之后,Django就知道要將它展示在admin的首頁了。


Django admin index page, now with polls displayed

Click “Questions”. Now you’re at the “change list” page for questions. This page displays all the questions in the database and lets you choose one to change it. There’s the “What’s up?” question we created earlier:

點擊“Questions”。 現(xiàn)在,你會進入Question的“變更列表”。 這個界面顯示了數(shù)據(jù)庫中的所有question,你可以選擇一個來更改它。 我們在前面創(chuàng)建的“What’s up?” 問題也在這里:

Polls change list page

Click the “What’s up?” question to edit it:


Editing form for question object

Things to note here:

  • The form is automatically generated from the Question model.

  • The different model field types (DateTimeField, CharField) correspond to the appropriate HTML input widget. Each type of field knows how to display itself in the Django admin.

  • Each 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.

注意事項:

  • 這個表單是根據(jù)Question模型文件自動生成的。

  • 模型中不同類型的字段(DateTimeField、CharField)會對應(yīng)相應(yīng)的HTML輸入控件。每一種類型的字段,Django管理站點都知道如何顯示它們。

  • 每個DateTimeField字段都會有個方便的JavaScript快捷鍵。Date有個“Today”的快捷鍵和一個彈出式日歷,time欄有個“Now”的快捷鍵和一個列出常用時間選項的彈出式窗口。

界面的底部提供了幾個按鈕:

  • save —— 保存更改,并返回當前類型對象的變更列表界面。

  • save and continue editing —— 保存更改并且重新載入當前對象的管理界面。

  • save and add another —— 保存更改并且載入一個當前類型對象的新的、空白的表單。

  • selete —— 顯示一個刪除確認界面。

If the value of “Date published” doesn’t match the time when you created the question in Tutorial 1, it probably means you forgot to set the correct value for the TIME_ZONE
setting. Change it, reload the page and check that the correct value appears.

如果“Date published”的值和你在教程1中創(chuàng)建這個Question對象時的時間不相符,可能是因為你忘記將TIME_ZONE設(shè)置為你當?shù)氐臅r區(qū)。修改它,然后刷新界面,再次檢查一下是否正確。

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:

通過“Today”和“Now”這兩個快捷鍵更改“Date published”字段。,然后點擊 “Save and continue editing”。然后點擊右上角的“History”按鈕。 你將看到一個頁面,列出了通過Django管理界面對此對象所做的全部更改的清單,包含有時間戳和修改人的姓名等信息:

History page for question object
When you’re comfortable with the models API and have familiarized yourself with the admin site, read part 3 of this tutorial to learn about how to add more views to our polls app.

當你適應(yīng)了models的API,熟悉了admin站點后,請移步
教程第三部分 來學習如何給投票應(yīng)用編寫更多的views函數(shù).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容