Django文档翻译:模型参考(Model Reference)

Python 专栏收录该内容
135 篇文章 0 订阅
Django文档翻译:模型参考(Model Reference)
翻译者:木野狐(Neil Chen)
Django 版本:0.95.1
进度:未完,持续更新中。
最后更新时间:2007-2-22

 


body,table,td,p,.pre {font-size:9pt; font-family:Arial, Helvetica, sans-serif;} .pre{font-family:"Courier New", Courier, mono; color:navy;} .tran_cn{color:#FF9900; font-weight:bold;} .code{background-color:#CCCCCC; font-size:9pt; font-family:"Courier New", Courier, mono;} .comment{color:#009900;} /* :Author: David Goodger :Contact: goodger@python.org :Date: $Date: 2006-05-21 22:44:42 +0200 (Sun, 21 May 2006) $ :Revision: $Revision: 4564 $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to customize this style sheet. */ /* used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { border: 0 } table.borderless td, table.borderless th { /* Override padding for "table.docutils td" with "! important". The right padding separates the table cells. */ padding: 0 0.5em 0 0 ! important } .first { /* Override more specific margin styles with "! important". */ margin-top: 0 ! important } .last, .with-subtitle { margin-bottom: 0 ! important } .hidden { display: none } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } /* Uncomment (and remove this text!) to get bold-faced definition list terms dl.docutils dt { font-weight: bold } */ div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title { color: red ; font-weight: bold ; font-family: sans-serif } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } */ div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em ; margin-right: 2em } div.footer, div.header { clear: both; font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin-left: 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { margin-top: 0.4em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } img.align-left { clear: left } img.align-right { clear: right } ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font-family: serif ; font-size: 100% } pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em } span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.pre { white-space: pre } span.problematic { color: red } span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { border-left: solid 1px gray; margin-left: 1px } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid 1px black; margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; white-space: nowrap ; padding-left: 0 } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } ul.auto-toc { list-style-type: none }

Model reference
模型参考

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. Generally, each model maps to a single database table.

The basics:

  • Each model is a Python class that subclasses django.db.models.Model.
  • Each attribute of the model represents a database field.
  • Model metadata (non-field information) goes in an inner class named Meta.
  • Metadata used for Django's admin site goes into an inner class named Admin.
  • With all of this, Django gives you an automatically-generated database-access API, which is explained in the Database API reference.

A companion to this document is the official repository of model examples. (In the Django source distribution, these examples are in the tests/modeltests directory.)

Quick example

This example model defines a Person, which has a first_name and last_name:

from django.db import models

class Person(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)

first_name and last_name are fields of the model. Each field is specified as a class attribute, and each attribute maps to a database column.

The above Person model would create a database table like this:

CREATE TABLE myapp_person (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);

Some technical notes:

  • The name of the table, myapp_person, is automatically derived from some model metadata but can be overridden. See Table names below.
    表名 myapp_person 从模型的元数据自动产生,但也可以被重写。
  • An id field is added automatically, but this behavior can be overriden. See Automatic primary key fields below.
    id 字段是自动附加的,也可以被重写。
  • The CREATE TABLE SQL in this example is formatted using PostgreSQL syntax, but it's worth noting Django uses SQL tailored to the database backend specified in your settings file.

Fields

The most important part of a model -- and the only required part of a model -- is the list of database fields it defines. Fields are specified by class attributes.

Example:


class Musician(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
instrument = models.CharField(maxlength=100)


class Album(models.Model):
artist = models.ForeignKey(Musician)
# 定义外键
name = models.CharField(maxlength=100)
release_date = models.DateField()
# 日期字段
num_stars = models.IntegerField()

Field name restrictions

Django places only two restrictions on model field names:

  1. A field name cannot be a Python reserved word, because that would result in a Python syntax error. For example:
    字段名不能是 Python 保留字

    class Example(models.Model):
    pass = models.IntegerField() # 'pass' is a reserved word!
  2. A field name cannot contain more than one underscore in a row, due to the way Django's query lookup syntax works. For example:
    字段名不能包含多于一个下划线。因为 Django 的 query 查找语法。

    class Example(models.Model):
    foo__bar = models.IntegerField() 'foo__bar' has two underscores!

These limitations can be worked around, though, because your field name doesn't necessarily have to match your database column name. See db_column below.

SQL reserved words, such as join, where or select, are allowed as model field names, because Django escapes all database table names and column names in every underlying SQL query. It uses the quoting syntax of your particular database engine.
SQL 保留字,如 join, where, select,可以被用作模型的字段名。

Field types

Each field in your model should be an instance of the appropriate Field class. Django uses the field class types to determine a few things:

  • The database column type (e.g. INTEGER, VARCHAR).
  • The widget to use in Django's admin interface, if you care to use it (e.g. <input type="text">, <select>).
  • The minimal validation requirements, used in Django's admin and in manipulators.

Here are all available field types:

AutoField
自增字段

An IntegerField that automatically increments according to available IDs. You usually won't need to use this directly; a primary key field will automatically be added to your model if you don't specify otherwise. See Automatic primary key fields.
是自增的 IntegerField. 一般不需要直接操作它。如果除此之外未指定其他的字段为主键,则自增字段会被设置为主键。

BooleanField
布尔型字段

A true/false field.

The admin represents this as a checkbox.

CharField
字符串型字段

A string field, for small- to large-sized strings.

For large amounts of text, use TextField.
大文本用 TextField.

The admin represents this as an <input type="text"> (a single-line input).

CharField has an extra required argument, maxlength, the maximum length (in characters) of the field. The maxlength is enforced at the database level and in Django's validation.
CharField 的构造器需要额外提供 maxlength 参数,这是必须的。

CommaSeparatedIntegerField
逗号分割的整数字段

A field of integers separated by commas. As in CharField, the maxlength argument is required.
和 CharField 一样,必须向其构造器传递 maxlength 参数。

DateField
日期字段

A date field. Has a few extra optional arguments:

ArgumentDescription
auto_nowAutomatically set the field to now every time the object is saved. Useful for "last-modified" timestamps. Note that the current date is always used; it's not just a default value that you can override.
当对象被保存时,自动设置为现在时间。可用于表示最后修改时间的时间戳。注意:当前日期总是会被使用,而不是仅仅一个默认值。
auto_now_addAutomatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it's not just a default value that you can override.
当对象被初次创建的时候,自动设置为现在时间。可用于表示创建时间的时间戳。注意:当前日期总是被使用,而不仅仅是一个默认值。

The admin represents this as an <input type="text"> with a JavaScript calendar and a shortcut for "Today."

DateTimeField
时间日期字段

A date and time field. Takes the same extra options as DateField.
拥有和 DateField 一样的两个额外选项(auto_now, auto_now_add).

The admin represents this as two <input type="text"> fields, with JavaScript shortcuts.

EmailField

A CharField that checks that the value is a valid e-mail address. This doesn't accept maxlength.
能够验证是合法的 email 的 CharField 字段。不接受 maxlength.

FileField

A file-upload field.
文件上传字段

Has an extra required argument, upload_to, a local filesystem path to which files should be upload. This path may contain strftime formatting, which will be replaced by the date/time of the file upload (so that uploaded files don't fill up the given directory).
有一个额外的参数,upload_to, 表示一个本地文件路径,用于存放文件。此路径可以包含 strftime 格式化。

The admin represents this as an <input type="file"> (a file-upload widget).

Using a FileField or an ImageField (see below) in a model takes a few steps:
在模型中使用 FileField 或 ImageField 需要下列步骤:

  1. In your settings file, you'll need to define MEDIA_ROOT as the full path to a directory where you'd like Django to store uploaded files. (For performance, these files are not stored in the database.) Define MEDIA_URL as the base public URL of that directory. Make sure that this directory is writable by the Web server's user account.
    在 settings 文件中,定义 MEDIA_ROOT 为保存上传文件的目录的全路径。
  2. Add the FileField or ImageField to your model, making sure to define the upload_to option to tell Django to which subdirectory of MEDIA_ROOT it should upload files.
    向模型中添加 FileField 或 ImageField 字段。设置 upload_to 选项,指示 Django 将文件上传到 MEDIA_ROOT 的哪个子目录中。
  3. All that will be stored in your database is a path to the file (relative to MEDIA_ROOT). You'll must likely want to use the convenience get_<fieldname>_url function provided by Django. For example, if your ImageField is called mug_shot, you can get the absolute URL to your image in a template with {{ object.get_mug_shot_url }}.
    存储于数据库中的是文件的相对路径(相对于目录 MEDIA_ROOT). 可利用 get_<fieldname>_url 函数。举例来说,如果 ImageField 字段名为 mug_shot, 则可以在模版中通过 {{ object.get_mug_shot_url }} 字段获取图片的绝对路径。

FilePathField
文件路径字段

A field whose choices are limited to the filenames in a certain directory on the filesystem. Has three special arguments, of which the first is required:
该字段的值被限制为某个目录下的文件名。它有3个特殊参数,其中第一个参数是必要的。

ArgumentDescription
pathRequired. The absolute filesystem path to a directory from which this FilePathField should get its choices. Example: "/home/images".
必填。指向可选的文件名所在目录的名称。如:"/home/images".
matchOptional. A regular expression, as a string, that FilePathField will use to filter filenames. Note that the regex will be applied to the base filename, not the full path. Example: "foo.*/.txt^", which will match a file called foo23.txt but not bar.txt or foo23.gif.
可选。是一个正则表达式,FilePathField 用来过滤文件名。该正则表达式用于文件名的 base 部分,而不是全名。如:"foo.*/.txt^", 能够匹配 foo23.txt 而不能匹配 bar.txt 或 foo23.gif.
recursiveOptional. Either True or False. Default is False. Specifies whether all subdirectories of path should be included.
可选,默认值为 False. 表示 path 的子目录是否包括在内。

Of course, these arguments can be used together.

The one potential gotcha is that match applies to the base filename, not the full path. So, this example:
注意:下列代码中

FilePathField(path="/home/images", match="foo.*", recursive=True)

...will match /home/images/foo.gif but not /home/images/foo/bar.gif because the match applies to the base filename (foo.gif and bar.gif).
能匹配 /home/images/foo.gif 但不匹配 /home/images/foo/bar.gif (因为匹配的是文件名的 base 部分)

FloatField
浮点数字段

A floating-point number. Has two required arguments
有两个必须的字段 :

ArgumentDescription
max_digitsThe maximum number of digits allowed in the number.
数字长度
decimal_placesThe number of decimal places to store with the number.
十进制位的数目,即有效位数

For example, to store numbers up to 999 with a resolution of 2 decimal places, you'd use:

models.FloatField(..., max_digits=5, decimal_places=2)

And to store numbers up to approximately one billion with a resolution of 10 decimal places:

models.FloatField(..., max_digits=19, decimal_places=10)

The admin represents this as an <input type="text"> (a single-line input).

ImageField
图片字段

Like FileField, but validates that the uploaded object is a valid image. Has two extra optional arguments, height_field and width_field, which, if set, will be auto-populated with the height and width of the image each time a model instance is saved.
类似于 FileField, 但会验证上传的对象是否为图片。 有两个额外的可选字段:height_field 和 width_field

Requires the Python Imaging Library.

IntegerField
整数字段

An integer.

The admin represents this as an <input type="text"> (a single-line input).

IPAddressField
IP 地址字段

An IP address, in string format (i.e. "24.124.1.30").

The admin represents this as an <input type="text"> (a single-line input).

NullBooleanField
允许为空的布尔型字段

Like a BooleanField, but allows NULL as one of the options. Use this instead of a BooleanField with null=True.
可以用这个字段类型代替设置了 null=True 属性的 BooleanField.

The admin represents this as a <select> box with "Unknown", "Yes" and "No" choices.

PhoneNumberField
电话号码字段

A CharField that checks that the value is a valid U.S.A.-style phone number (in the format XXX-XXX-XXXX).
表示美国电话号码的格式的字段(xxx-xxx-xxxx)

PositiveIntegerField
正整数字段

Like an IntegerField, but must be positive.

PositiveSmallIntegerField
小的正整数字段

Like a PositiveIntegerField, but only allows values under a certain (database-dependent) point.
最大值取决于具体的数据库特性

SlugField

"Slug" is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They're generally used in URLs.
"Slug" 是报纸的术语。表示一个短的标签,仅包含字母,数字,下划线或连字符。一般用于 URL 中。

In the Django development version, you can specify maxlength. If maxlength is not specified, Django will use a default length of 50. In previous Django versions, there's no way to override the length of 50.
在 Django 开发版中,可指定 maxlength. 默认的长度是 50. 在低版本的 Django 中,没有办法可以覆盖长度为 50 的限制。

Implies db_index=True.
隐含 db_index=True

Accepts an extra option, prepopulate_from, which is a list of fields from which to auto-populate the slug, via JavaScript, in the object's admin form:
接受一个额外选项 prepopulate_from,用于指示在 admin 表单中的可选值。

models.SlugField(prepopulate_from=("pre_name", "name"))

prepopulate_from doesn't accept DateTimeFields.
prepopulate_from 不接受 DateTimeField 字段

The admin represents SlugField as an <input type="text"> (a single-line input).

SmallIntegerField
小整数字段

Like an IntegerField, but only allows values under a certain (database-dependent) point.

TextField
大文本字段

A large text field.

The admin represents this as a <textarea> (a multi-line input).

TimeField
时间字段

A time. Accepts the same auto-population options as DateField and DateTimeField.
和 DateField 以及 DateTimeField 一样也有两个时间戳字段。

The admin represents this as an <input type="text"> with some JavaScript shortcuts.

URLField

A field for a URL. If the verify_exists option is True (default), the URL given will be checked for existence (i.e., the URL actually loads and doesn't give a 404 response).
表示 URL 的字段。如果 verify_exists 选项为 True(默认),则会检查 URL 的可用性(比方说,URL 能够加载,并且反馈 404 错误)。

The admin represents this as an <input type="text"> (a single-line input).

USStateField
两个字母表示的美国州名字段

A two-letter U.S. state abbreviation.

The admin represents this as an <input type="text"> (a single-line input).

XMLField
XML 字段

A TextField that checks that the value is valid XML that matches a given schema. Takes one required argument, schema_path, which is the filesystem path to a RelaxNG schema against which to validate the field.
表示 XML 文档的 TextField. 会针对指定的 schema 验证其有效性。接受一个必选参数 schema_path.

Field options

The following arguments are available to all field types. All are optional.
下面两个是对所有字段都有效的选项,两者都是可选值。

null

If True, Django will store empty values as NULL in the database. Default is False.
如果为 True, Django 会保存空字符串为 NULL 到数据库,默认是 False.

Note that empty string values will always get stored as empty strings, not as NULL -- so use null=True for non-string fields such as integers, booleans and dates.
注意空字符串会保存为空字符串,而不是 NULL,所以对于非字符串类型的字段,比如整数,布尔值以及日期,需要设定 null=True.

Avoid using null on string-based fields such as CharField and TextField unless you have an excellent reason. If a string-based field has null=True, that means it has two possible values for "no data": NULL, and the empty string. In most cases, it's redundant to have two possible values for "no data;" Django convention is to use the empty string, not NULL.
对于基于字符串类型的字段如 CharField, TextField 要避免使用 null. 除非有特别的理由。如果一个基于字符串的字段类型设置了 null=True, 这就意味着有两种可能的值用于表示“没有数据”:NULL 和空字符串。在大多数情况下,用两种值表示没有数据是冗余的,所以 Django 的惯例是使用空字符串,而不是 NULL.

blank

If True, the field is allowed to be blank.
如果为 True, 该字段允许留空。

Note that this is different than null. null is purely database-related, whereas blank is validation-related. If a field has blank=True, validation on Django's admin site will allow entry of an empty value. If a field has blank=False, the field will be required.
和 null 的区别:null 是完全相对数据库的概念,而 blank 是对数据校验(validation)而言的。 如果 blank=True, 则 Django 的 admin 后台校验功能会允许空值,否则字段为必填。

choices

An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this field.
由二元组的可枚举集合(list 或 tuple 或其他)所代表的字段可选值。

If this is given, Django's admin will use a select box instead of the standard text field and will limit choices to the choices given.
Django 的 admin 会使用下拉框代替文本框,限制可选值的范围。

A choices list looks like this:

YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
)

The first element in each tuple is the actual value to be stored. The second element is the human-readable name for the option.
每个 tuple 的第一个元素是选项值,第二个是方便阅读的选项名称。

The choices list can be defined either as part of your model class:
可选值的列表可以定义在模型类里面:

class Foo(models.Model):
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)

or outside your model class altogether:
也可以定义在外部:

GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
class Foo(models.Model):
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)

Finally, note that choices can be any iterable object -- not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever.
最后一点,请注意可选值可以是任意可枚举的对象:不一定要是 list 或 tuple. 这使得我们可以动态的构建选项集合对象。但是,如果你发现你需要动态构建选项列表对象时,也许使用一个外键表会更好,搭配 ForeignKey 字段设定。choices 是为那些几乎从来不发生变化的静态选项集合而设定的。

core

For objects that are edited inline to a related object.
为了以内联的方式编辑对象,设定到一个关联对象的需要而设定。

In the Django admin, if all "core" fields in an inline-edited object are cleared, the object will be deleted.
在 Django admin 中,如果某个内联编辑(inline-edited) 的对象的所有 "core" 字段都被清空,则该对象会被删除。

It is an error to have an inline-editable relation without at least one core=True field.
如果设定了内联编辑关系,却不设置至少一个 core=True 字段,这是做错误的。

Please note that each field marked "core" is treated as a required field by the Django admin site. Essentially, this means you should put core=True on all required fields in your related object that is being edited inline.
注意,所有被标注为 "core" 的字段都会被 Django Admin 当作必填字段。本质上,这就是说你需要对所有内联编辑的相关对象上加 core=True 字段

db_column

The name of the database column to use for this field. If this isn't given, Django will use the field's name.
用于标注对应于字段属性的数据库列名称。如果不提供,则会直接使用字段属性的名称。

If your database column name is an SQL reserved word, or contains characters that aren't allowed in Python variable names -- notably, the hyphen -- that's OK. Django quotes column and table names behind the scenes.
一般可以用这个办法来应付数据库字段和 SQL 保留字冲突的情况,或者和 Python 变量名冲突的情况(比如连字符不允许出现在 Python 变量名中)。

db_index

If True, django-admin.py sqlindexes will output a CREATE INDEX statement for this field.
如果为 True, django-admin.py sqlindexes 会为此语句输出一个 CREATE INDEX 语句。

default

The default value for the field.
字段的默认值

editable

If False, the field will not be editable in the admin. Default is True.
如果为 False, 该字段在 admin 中不能被编辑。默认是 True.

help_text

Extra "help" text to be displayed under the field on the object's admin form. It's useful for documentation even if your object doesn't have an admin form.
用于显示在 admin 表单中的额外的帮助信息。即使不使用 admin 表单,这个字段也非常适合与文档功能。

primary_key

If True, this field is the primary key for the model.
如果是 True, 该字段为主键。

If you don't specify primary_key=True for any fields in your model, Django will automatically add this field:
如果在某个模型中没有设置任何字段为 primary_key=True, 则 Django 会自动生成一个 id 字段:

id = models.AutoField('ID', primary_key=True)

Thus, you don't need to set primary_key=True on any of your fields unless you want to override the default primary-key behavior.
一般不需要在任何字段上设置 primary_key=True, 除非你要覆盖自动产生 id 的行为。

primary_key=True implies blank=False, null=False and unique=True. Only one primary key is allowed on an object.
primary_key=True 暗示着 blank=False, null=False 并且 unique=True. 一个对象只能有一个主键。

radio_admin

By default, Django's admin uses a select-box interface (<select>) for fields that are ForeignKey or have choices set. If radio_admin is set to True, Django will use a radio-button interface instead.
默认情况下,Django admin 用下拉框来选择 ForeignKey 或 choices. 如果设定 radio_admin=True, 则会用但旋钮代替。

Don't use this for a field unless it's a ForeignKey or has choices set.
如果字段不是 ForeignKey 或 choices, 不要用这个属性。

unique

If True, this field must be unique throughout the table.
如果为 True, 则该字段值在表中是唯一的。

This is enforced at the database level and at the Django admin-form level.
这个选项同时约束在数据库级别和 Django admin 表单中。

unique_for_date

Set this to the name of a DateField or DateTimeField to require that this field be unique for the value of the date field.
将这个属性值设定为某个 DateField 或 DateTimeField 字段的名称,使得此字段值相关的日期唯一。

For example, if you have a field title that has unique_for_date="pub_date", then Django wouldn't allow the entry of two records with the same title and pub_date.
举例来说,如果你有个字段 title, 在其上设定了 unique_for_date="pub_date", 那么 Django 就不会允许产生两条 title 和 pub_date 都相同的记录。

This is enforced at the Django admin-form level but not at the database level.
这个限制仅在 Django admin-form 上起作用,而不约束数据库。

unique_for_month

Like unique_for_date, but requires the field to be unique with respect to the month.
和 unique_for_date 类似,但要求字段相对月份是唯一的。

unique_for_year

Like unique_for_date and unique_for_month.
和 unique_for_date 以及 unique_for_month 类似。

validator_list

A list of extra validators to apply to the field. Each should be a callable that takes the parameters field_data, all_data and raises django.core.validators.ValidationError for errors. (See the validator docs.)
针对该字段的一系列额外的验证器的列表。其中每个验证器都应该是 callable, 其参数为 field_data, all_data,错误时抛出的异常为 django.core.validators.ValidationError.

Django comes with quite a few validators. They're in django.core.validators.
Django 自带了很多验证器,都在 django.core.validators 下。

Verbose field names

Each field type, except for ForeignKey, ManyToManyField and OneToOneField, takes an optional first positional argument -- a verbose name. If the verbose name isn't given, Django will automatically create it using the field's attribute name, converting underscores to spaces.
每个字段,除了 ForeignKey, ManyToManyField 和 OneToOneField 之外,可以接受第一个可选参数:即此字段的描述名称。如果没有提供,Django 会根据属性名称自动创建一个,在此过程中,会把下划线转化为空格。

In this example, the verbose name is "Person's first name":

first_name = models.CharField("Person's first name", maxlength=30)

In this example, the verbose name is "first name":

first_name = models.CharField(maxlength=30)

ForeignKey, ManyToManyField and OneToOneField require the first argument to be a model class, so use the verbose_name keyword argument:
ForeignKey, ManyToManyField 和 OneToOneField 要求第一个参数是一个 Model 类,因此需要用 verbose_name 这个关键字参数:

poll = models.ForeignKey(Poll, verbose_name="the related poll")
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(Place, verbose_name="related place")

Convention is not to capitalize the first letter of the verbose_name. Django will automatically capitalize the first letter where it needs to.
惯例是 verbose_name 的首字母不需要大写。因为 Django 会在需要的时候把它自动转化为大写形式。

Relationships
关系

Clearly, the power of relational databases lies in relating tables to each other. Django offers ways to define the three most common types of database relationships: Many-to-one, many-to-many and one-to-one.
很显然,关系型数据库的威力就在于表之间的相互关联。Django 提供了办法来定义最常见的三种表间关联的类型:多对一,多对多,一对一。

Many-to-one relationships
多对一关联

To define a many-to-one relationship, use ForeignKey. You use it just like any other Field type: by including it as a class attribute of your model.
要定义多对一关联,使用 ForeignKey. 只要像其他字段类型一样使用它即可:将它定义为 Model 类的一个属性。

ForeignKey requires a positional argument: The class to which the model is related.
ForeignKey 需要一个位置确定的参数:和当前 Model 相关联的类。

For example, if a Car model has a Manufacturer -- that is, a Manufacturer makes multiple cars but each Car only has one Manufacturer -- use the following definitions:
举例来说,如果一个汽车(Car)模型对应一个制造商(Manufacturer),也就是说,一个制造商生产多个汽车,但一个汽车只有一个制造商。可以使用如下方式定义这种关系:

class Manufacturer(models.Model):
# ...

class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer)
# ...

To create a recursive relationship -- an object that has a many-to-one relationship with itself -- use models.ForeignKey('self').
如果要创建递归的关系:即一个对象和它自身有多对一的关系,使用 models.ForeignKey('self')

If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself:
如果要创建一个关系,而它所依赖的模型还未被创建,你可以用模型的名称(字符串形式),而不是模型对象自身:

class Car(models.Model):
manufacturer = models.ForeignKey('Manufacturer')
# ...

class Manufacturer(models.Model):
# ...

Note, however, that support for strings around model names in ForeignKey is quite new, and it can be buggy in some cases.
但是需要注意的是,这种用字符串形式的 ForeignKey 支持是比较新的特性,在某些情况下也许会产生 bug.

Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column. (You can change this explicitly by specifying db_column; see db_column below.) However, your code should never have to deal with the database column name, unless you write custom SQL. You'll always deal with the field names of your model object.
在幕后,Django 向字段属性名称上附加 "_id" 来构成数据库的列名称。在上面的例子中,数据库中对应于 Car 模型的表会产生一个名为 manufacturer_id 的字段。(你也可以显式的指定它,通过 db_column)。但是,你的代码应该从来不直接处理数据库列名称,除非你要写自定义的 SQL. 你应该总是操作模型对象的字段属性名。

It's suggested, but not required, that the name of a ForeignKey field (manufacturer in the example above) be the name of the model, lowercase. You can, of course, call the field whatever you want. For example:
有一个建议,但不是必须的:ForeignKey 字段的名称(上述例子中的 manufacturer)是对应模型类名称的小写。但你也可以将它取为任意的名称,比如:

class Car(models.Model):
company_that_makes_it = models.ForeignKey(Manufacturer)
# ...

See the Many-to-one relationship model example for a full example.

ForeignKey fields take a number of extra arguments for defining how the relationship should work. All are optional:
ForeignKey 字段有一些额外的参数可以定义关系的具体形式,它们都是可选的:

ArgumentDescription
edit_inlineIf not False, this related object is edited "inline" on the related object's page. This means that the object will not have its own admin interface. Use either models.TABULAR or models.STACKED, which, respectively, designate whether the inline-editable objects are displayed as a table or as a "stack" of fieldsets.
如果不是 False, 则此对象会用内联的形式在相关对象页面直接编辑。这表示此对象没有它自己独立的管理界面。使用 models.TABULAR 或 models.STACKED 来标注,分别表示内联编辑的对象显示为表格还是 fieldsets 的 stack.
limit_choices_to

A dictionary of lookup arguments and values (see the Database API reference) that limit the available admin choices for this object. Use this with models.LazyDate to limit choices of objects by date. For example:
一个包含查找参数及其值的字典,用于限制对象可用的 admin choices,和 models.LazyDate 联用,用于按日期限制不同的选项,如:

limit_choices_to = {'pub_date__lte': models.LazyDate()}

only allows the choice of related objects with a pub_date before the current date/time to be chosen.
这个语句使得仅允许选择 pub_date 字段值在当前时间之前的那些日期。

Instead of a dictionary this can also be a Q object (an object with a get_sql() method) for more complex queries.
和字典不同的是,在负责的查询中,这个也可以是一个 Q对象(含有 get_sql() 方法的对象)

Not compatible with edit_inline.
和 edit_inline 不相容。

max_num_in_admin

For inline-edited objects, this is the maximum number of related objects to display in the admin. Thus, if a pizza could only have up to 10 toppings, max_num_in_admin=10 would ensure that a user never enters more than 10 toppings.
对于内联编辑的对象,这是显示在 admin 界面中相关对象的最大数目。

Note that this doesn't ensure more than 10 related toppings ever get created. It simply controls the admin interface; it doesn't enforce things at the Python API level or database level.
仅控制 admin 界面,对 Python API 或数据库层次没有限制。

min_num_in_adminThe minimum number of related objects displayed in the admin. Normally, at the creation stage, num_in_admin inline objects are shown, and at the edit stage num_extra_on_change blank objects are shown in addition to all pre-existing related objects. However, no fewer than min_num_in_admin related objects will ever be displayed.
在 admin 中显示的内联编辑对象的最少数目。通常,在创建阶段,会显示 num_in_admin 个内联对象,而在编辑阶段显示 num_extra_on_change 个额外的空对象。(排除已有的一些相关对象),然而,少于 min_num_in_admin 个相关对象的从来不被显示。
num_extra_on_changeThe number of extra blank related-object fields to show at the change stage.
对象在修改状态时,显示的额外的空白关联对象的数目。
num_in_adminThe default number of inline objects to display on the object page at the add stage.
对象在添加状态时,显示的内联编辑的相关对象数目。
raw_id_admin

Only display a field for the integer to be entered instead of a drop-down menu. This is useful when related to an object type that will have too many rows to make a select box practical.
仅显示一个可输入的整数值字段,而不是下拉列表。当关联对象在下拉框里显示会显得太多时,这很有用。

Not used with edit_inline.
不能和 edit_inline 选项一起设定。

related_nameThe name to use for the relation from the related object back to this one. See the related objects documentation for a full explanation and example.
设定从关联对象到自身的关系名称。
to_fieldThe field on the related object that the relation is to. By default, Django uses the primary key of the related object.
关联到的对象的字段名称。默认情况下,Django 使用关联对象的主键字段。

Many-to-many relationships
多对多关联

To define a many-to-many relationship, use ManyToManyField. You use it just like any other Field type: by including it as a class attribute of your model.
要定义多对多关联,用 ManyToManyField.

ManyToManyField requires a positional argument: The class to which the model is related.
ManyToManyField 需要一个位置确定的参数:关联的模型的类名称。

For example, if a Pizza has multiple Topping objects -- that is, a Topping can be on multiple pizzas and each Pizza has multiple toppings -- here's how you'd represent that:
举例来说,假如一个 Pizza 可以有多个 Topping 对象:也就是说,每个 Topping 可以在多个 pizza 上面,并且每个 Pizza 可以有多个 toppings. 那么你可以用如下的办法来定义模型:

class Topping(models.Model):
# ...

class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)

As with ForeignKey, a relationship to self can be defined by using the string 'self' instead of the model name, and you can refer to as-yet undefined models by using a string containing the model name.
和 ForeignKey 的设置一样,指向自身的多对多关联,可以用 'self' 来代替模型名称;指向尚未定义的模型时,可以用字符串形式表示。

It's suggested, but not required, that the name of a ManyToManyField (toppings in the example above) be a plural describing the set of related model objects.
建议将 ManyToManyField 设置为复数形式,但这不是必须的。

Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship.
在幕后,Django 会创建一个中间表来管理多对多关联。

It doesn't matter which model gets the ManyToManyField, but you only need it in one of the models -- not in both.
在多对多关联的哪一方模型中定义 ManyToManyField 并不重要,但你只需要定义一次,而不是两边都定义。

Generally, ManyToManyField instances should go in the object that's going to be edited in the admin interface, if you're using Django's admin. In the above example, toppings is in Pizza (rather than Topping having a pizzas ManyToManyField ) because it's more natural to think about a Pizza having toppings than a topping being on multiple pizzas. The way it's set up above, the Pizza admin form would let users select the toppings.
一般的,ManyToManyField 实例在 admin 界面中,会显示在其所属的对象的编辑界面,如果你使用 Django 的 admin 界面的话。在上述例子中,toppings 显示在 Pizza 中,因为,我们说“一个 Pizza 有多个 toppings" 要比 "一个 topping 在多个 pizzas 上面" 来的更自然。按照上面的设置,在 Pizza 的管理界面上将会让你选择 toppings 来编辑。

See the Many-to-many relationship model example for a full example.

ManyToManyField objects take a number of extra arguments for defining how the relationship should work. All are optional:
ManyToManyField 的一些可选参数:

ArgumentDescription
related_nameSee the description under ForeignKey above.
同 ForeignKey 的情形
filter_interfaceUse a nifty unobtrusive Javascript "filter" interface instead of the usability-challenged <select multiple> in the admin form for this object. The value should be models.HORIZONTAL or models.VERTICAL (i.e. should the interface be stacked horizontally or vertically).
在管理界面中,使用好看实用的 JavaScript "filter" 界面代替可用性受到挑战的 <select multiple>. 其值可以是 models.HORIZONTAL 或 models.VERTICAL (指界面排序的方向)。
limit_choices_toSee the description under ForeignKey above.
同 ForeignKey 的情形
symmetrical
对称的

Only used in the definition of ManyToManyFields on self. Consider the following model:
仅在对自身有多对多关联时定义此选项。考虑下列模型:

class Person(models.Model):
friends = models.ManyToManyField("self")

When Django processes this model, it identifies that it has a ManyToManyField on itself, and as a result, it doesn't add a person_set attribute to the Person class. Instead, the ManyToManyField is assumed to be symmetrical -- that is, if I am your friend, then you are my friend.
当 Django 处理这个模型时,它发现 Person 类有一个指向自身的 ManyToManyField 多对多关联,因此,它不会添加 person_set 属性到 Person 类中。相反的是,ManyToManyField 被假定是对称的:也就是说,如果我是你的朋友,则你一定是我的朋友。

If you do not want symmetry in ManyToMany relationships with self, set symmetrical to False. This will force Django to add the descriptor for the reverse relationship, allowing ManyToMany relationships to be non-symmetrical.
如果你不想把指向自身的多对多关联定义为对称的,设置 symmetrical=False 即可。这会让 Django 为反向关系添加 descriptor, 已实现不对称的多对多关系。

One-to-one relationships
一对一关联

The semantics of one-to-one relationships will be changing soon, so we don't recommend you use them. If that doesn't scare you away, keep reading.
在未来的 Django 版本中,一对一关联的语义即将发生变化,因此我们不建议使用一对一关联。如果这没把你吓坏,继续阅读吧。

To define a one-to-one relationship, use OneToOneField. You use it just like any other Field type: by including it as a class attribute of your model.
定义一对一关联使用 OneToOneField 字段即可。

This is most useful on the primary key of an object when that object "extends" another object in some way.
这对于通过和主键建立关联,扩展对象的属性为另一个对象的情形比较有用。

OneToOneField requires a positional argument: The class to which the model is related.
一对一字段需要一个位置确定的参数:关联模型的类名称。

For example, if you're building a database of "places", you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself and replicating those fields in the Restaurant model, you could make Restaurant have a OneToOneField to Place (because a restaurant "is-a" place).
举例来说,如果你在建立一个关于“地点”信息的数据库,那么,你一定会建立一些很标准的信息,比如地址,电话号码等。那么如果你要建立另一个餐馆信息的数据库,而这些餐馆是基于上述“地点”信息的,你不需要通过复制地点信息的相关字段到“餐馆”模型中,而只要让“餐馆“建立到“地点”的一对一关联即可(OneToOneField). (因此“餐馆”是“地点”的一种)。

As with ForeignKey, a relationship to self can be defined by using the string "self" instead of the model name; references to as-yet undefined models can be made by using a string containing the model name.
和 ForeignKey 的情形一样,指向自身的一对一关联也可以用 "self" 来设定指向的模型名称; 指向尚未定义的模型时,用字符串形式表示。

This OneToOneField will actually replace the primary key id field (since one-to-one relations share the same primary key), and will be displayed as a read-only field when you edit an object in the admin interface:
OneToOneField 会覆盖主键 id 字段(因此一对一关联共享一个主键),并且会在 admin 界面中会显示为一个只读字段。

See the One-to-one relationship model example for a full example.

Meta options

在模型类中添加内嵌的 class Meta 可以定义一些元数据信息:

class Foo(models.Model):
bar = models.CharField(maxlength=30)

class Meta:
# ...

模型的元数据是除了字段声明之外的其他一些信息,比如排序选项等。

下面是所有 Meta 选项的列表,所有都不是必须的。

db_table

对应于模型的数据库表的名字:

db_table = 'music_album'

如果不给出这个选项,Django 用下列格式自动生成一个表名: app_label + '_' + model_class_name. 详细的参见下面的 "Table names" 部分。

如果你的表名是 SQL 保留字,或者包含 Python 中不允许出现在变量名中的字符(比如连字符),这不要紧。Django 会在背后自动处理表名和列名的转换。

get_latest_by

是模型中某个 DateField 或 DateTimeField 字段的名称。用于指定在模型的管理器中 latest() 方法会使用的默认字段。

例子:

get_latest_by = "order_date"

See the docs for latest() for more.

order_with_respect_to

标注当前对象对给定的字段是可排序的。几乎总是被使用在允许按照某个父对象排序的关联对象中,比如,一个 Answer 对应于一个 Question 对象,而一个 Question 可以有多个 Answer,而我们关心答案的次序。你可以这样写:

class Answer(models.Model):
question = models.ForeignKey(Question)
# ...

class Meta:
order_with_respect_to = 'question'

ordering

对象的默认排序规则。在获取对象列表时使用:

ordering = ['-order_date']

这是一个字符串的 list 或 tuple. 每个字符串是一个字段名,它们可以有一个可选的前缀 '-' 字符,表示倒序排列。如果要随机次序排序,可以用 "?" 前缀。

例如,按 pub_date 字段升序排列:

ordering = ['pub_date']

倒序:

ordering = ['-pub_date']

先按 pub_date 降序,然后按 author 升序:

ordering = ['-pub_date', 'author']

See Specifying ordering for more examples.

注意:不管在 ordering 中写了多少个字段,admin 后台只用第一个。

permissions

创建对象时需要写到权限表中的额外的权限。对每一个有 admin 设置的对象,添加、修改、删除权限会自动创建。下面的例子定义了一个额外的权限:can_deliver_pizzas:

permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)

This is a list or tuple of 2-tuples in the format (permission_code, human_readable_permission_name).

unique_together

(译注:类似于联合主键)定义哪些字段组合后是必须唯一的:

unique_together = (("driver", "restaurant"),)

这个被用在 Django admin 中,同时数据库中也会创建相关的约束。
This is a list of lists of fields that must be unique when considered together. It's used in the Django admin and is enforced at the database level (i.e., the appropriate UNIQUE statements are included in the CREATE TABLE statement).

verbose_name

A human-readable name for the object, singular:

verbose_name = "pizza"

If this isn't given, Django will use a munged version of the class name: CamelCase becomes camel case.

verbose_name_plural

The plural name for the object:

verbose_name_plural = "stories"

If this isn't given, Django will use verbose_name + "s".

Table names

To save you time, Django automatically derives the name of the database table from the name of your model class and the app that contains it. A model's database table name is constructed by joining the model's "app label" -- the name you used in manage.py startapp -- to the model's class name, with an underscore between them.

For example, if you have an app bookstore (as created by manage.py startapp bookstore), a model defined as class Book will have a database table named bookstore_book.

To override the database table name, use the db_table parameter in class Meta.

Automatic primary key fields

By default, Django gives each model the following field:

id = models.AutoField(primary_key=True)

This is an auto-incrementing primary key.

If you'd like to specify a custom primary key, just specify primary_key=True on one of your fields. If Django sees you've explicitly set primary_key, it won't add the automatic id column.

Each model requires exactly one field to have primary_key=True.

Admin options

If you want your model to be visible to Django's admin site, give your model an inner "class Admin", like so:

class Person(models.Model):
first_name = models.CharField(maxlength=30)
last_name = models.CharField(maxlength=30)

class Admin:
# Admin options go here
pass

The Admin class tells Django how to display the model in the admin site.

Here's a list of all possible Admin options. None of these options are required. To use an admin interface without specifying any options, use pass, like so:

class Admin:
pass

Adding class Admin to a model is completely optional.

date_hierarchy

Set date_hierarchy to the name of a DateField or DateTimeField in your model, and the change list page will include a date-based drilldown navigation by that field.

Example:

date_hierarchy = 'pub_date'

fields

Set fields to control the layout of admin "add" and "change" pages.

fields is a list of two-tuples, in which each two-tuple represents a <fieldset> on the admin form page. (A <fieldset> is a "section" of the form.)

The two-tuples are in the format (name, field_options), where name is a string representing the title of the fieldset and field_options is a dictionary of information about the fieldset, including a list of fields to be displayed in it.

A full example, taken from the django.contrib.flatpages.FlatPage model:

class Admin:
fields = (
(None, {
'fields': ('url', 'title', 'content', 'sites')
}),
('Advanced options', {
'classes': 'collapse',
'fields' : ('enable_comments', 'registration_required', 'template_name')
}),
)

This results in an admin page that looks like:

http://media.djangoproject.com/img/doc/flatfiles_admin.png

If fields isn't given, Django will default to displaying each field that isn't an AutoField and has editable=True, in a single fieldset, in the same order as the fields are defined in the model.

The field_options dictionary can have the following keys:

fields

A tuple of field names to display in this fieldset. This key is required.

Example:

{
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
}

To display multiple fields on the same line, wrap those fields in their own tuple. In this example, the first_name and last_name fields will display on the same line:

{
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
}

classes

A string containing extra CSS classes to apply to the fieldset.

Example:

{
'classes': 'wide',
}

Apply multiple classes by separating them with spaces. Example:

{
'classes': 'wide extrapretty',
}

Two useful classes defined by the default admin-site stylesheet are collapse and wide. Fieldsets with the collapse style will be initially collapsed in the admin and replaced with a small "click to expand" link. Fieldsets with the wide style will be given extra horizontal space.

description

A string of optional extra text to be displayed at the top of each fieldset, under the heading of the fieldset. It's used verbatim, so you can use any HTML and you must escape any special HTML characters (such as ampersands) yourself.

js

A list of strings representing URLs of JavaScript files to link into the admin screen via <script src=""> tags. This can be used to tweak a given type of admin page in JavaScript or to provide "quick links" to fill in default values for certain fields.

list_display

Set list_display to control which fields are displayed on the change list page of the admin.

Example:

list_display = ('first_name', 'last_name')

If you don't set list_display, the admin site will display a single column that displays the __str__() representation of each object.

A few special cases to note about list_display:

  • If the field is a ForeignKey, Django will display the __str__() of the related object.

  • ManyToManyField fields aren't supported, because that would entail

    executing a separate SQL statement for each row in the table.

  • If the field is a BooleanField, Django will display a pretty "on" or "off" icon instead of True or False.

  • If the string given is a method of the model, Django will call it and display the output. This method should have a short_description function attribute, for use as the header for the field.

    Here's a full example model:

    class Person(models.Model):
    name = models.CharField(maxlength=50)
    birthday = models.DateField()

    class Admin:
    list_display = ('name', 'decade_born_in')

    def decade_born_in(self):
    return self.birthday.strftime('%Y')[:3] + "0's"
    decade_born_in.short_description = 'Birth decade'
  • If the string given is a method of the model, Django will HTML-escape the output by default. If you'd rather not escape the output of the method, give the method an allow_tags attribute whose value is True.

    Here's a full example model:

    class Person(models.Model):
    first_name = models.CharField(maxlength=50)
    last_name = models.CharField(maxlength=50)
    color_code = models.CharField(maxlength=6)

    class Admin:
    list_display = ('first_name', 'last_name', 'colored_name')

    def colored_name(self):
    return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
    colored_name.allow_tags = True

list_filter

Set list_filter to activate filters in the right sidebar of the change list page of the admin. This should be a list of field names, and each specified field should be either a BooleanField, DateField, DateTimeField or ForeignKey.

This example, taken from the django.contrib.auth.models.User model, shows how both list_display and list_filter work:

class Admin:
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser')

The above code results in an admin change list page that looks like this:

http://media.djangoproject.com/img/doc/users_changelist.png

(This example also has search_fields defined. See below.)

list_per_page

Set list_per_page to control how many items appear on each paginated admin change list page. By default, this is set to 100.

ordering

Set ordering to specify how objects on the admin change list page should be ordered. This should be a list or tuple in the same format as a model's ordering parameter.

If this isn't provided, the Django admin will use the model's default ordering.

save_as

Set save_as to enable a "save as" feature on admin change forms.

Normally, objects have three save options: "Save", "Save and continue editing" and "Save and add another". If save_as is True, "Save and add another" will be replaced by a "Save as" button.

"Save as" means the object will be saved as a new object (with a new ID), rather than the old object.

By default, save_as is set to False.

save_on_top

Set save_on_top to add save buttons across the top of your admin change forms.

Normally, the save buttons appear only at the bottom of the forms. If you set save_on_top, the buttons will appear both on the top and the bottom.

By default, save_on_top is set to False.

search_fields

Set search_fields to enable a search box on the admin change list page. This should be set to a list of field names that will be searched whenever somebody submits a search query in that text box.

These fields should be some kind of text field, such as CharField or TextField.

When somebody does a search in the admin search box, Django splits the search query into words and returns all objects that contain each of the words, case insensitive, where each word must be in at least one of search_fields. For example, if search_fields is set to ['first_name', 'last_name'] and a user searches for john lennon, Django will do the equivalent of this SQL WHERE clause:

WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')

Managers

A Manager is the interface through which database query operations are provided to Django models. At least one Manager exists for every model in a Django application.

The way Manager classes work is documented in the Retrieving objects section of the database API docs, but this section specifically touches on model options that customize Manager behavior.

Manager names

By default, Django adds a Manager with the name objects to every Django model class. However, if you want to use objects as a field name, or if you want to use a name other than objects for the Manager, you can rename it on a per-model basis. To rename the Manager for a given class, define a class attribute of type models.Manager() on that model. For example:

from django.db import models

class Person(models.Model):
#...
people = models.Manager()

Using this example model, Person.objects will generate an AttributeError exception, but Person.people.all() will provide a list of all Person objects.

Custom Managers

You can use a custom Manager in a particular model by extending the base Manager class and instantiating your custom Manager in your model.

There are two reasons you might want to customize a Manager: to add extra Manager methods, and/or to modify the initial QuerySet the Manager returns.

Adding extra Manager methods

Adding extra Manager methods is the preferred way to add "table-level" functionality to your models. (For "row-level" functionality -- i.e., functions that act on a single instance of a model object -- use Model methods, not custom Manager methods.)

A custom Manager method can return anything you want. It doesn't have to return a QuerySet.

For example, this custom Manager offers a method with_counts(), which returns a list of all OpinionPoll objects, each with an extra num_responses attribute that is the result of an aggregate query:

class PollManager(models.Manager):
def with_counts(self):
from django.db import connection
cursor = connection.cursor()
cursor.execute("""
SELECT p.id, p.question, p.poll_date, COUNT(*)
FROM polls_opinionpoll p, polls_response r
WHERE p.id = r.poll_id
GROUP BY 1, 2, 3
ORDER BY 3 DESC""")
result_list = []
for row in cursor.fetchall():
p = self.model(id=row[0], question=row[1], poll_date=row[2])
p.num_responses = row[3]
result_list.append(p)
return result_list

class OpinionPoll(models.Model):
question = models.CharField(maxlength=200)
poll_date = models.DateField()
objects = PollManager()

class Response(models.Model):
poll = models.ForeignKey(Poll)
person_name = models.CharField(maxlength=50)
response = models.TextField()

With this example, you'd use OpinionPoll.objects.with_counts() to return that list of OpinionPoll objects with num_responses attributes.

Another thing to note about this example is that Manager methods can access self.model to get the model class to which they're attached.

Modifying initial Manager QuerySets

A Manager's base QuerySet returns all objects in the system. For example, using this model:

class Book(models.Model):
title = models.CharField(maxlength=100)
author = models.CharField(maxlength=50)

...the statement Book.objects.all() will return all books in the database.

You can override a Manager's base QuerySet by overriding the Manager.get_query_set() method. get_query_set() should return a QuerySet with the properties you require.

For example, the following model has two Managers -- one that returns all objects, and one that returns only the books by Roald Dahl:

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
def get_query_set(self):
return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')

# Then hook it into the Book model explicitly.
class Book(models.Model):
title = models.CharField(maxlength=100)
author = models.CharField(maxlength=50)

objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.

With this sample model, Book.objects.all() will return all books in the database, but Book.dahl_objects.all() will only return the ones written by Roald Dahl.

Of course, because get_query_set() returns a QuerySet object, you can use filter(), exclude() and all the other QuerySet methods on it. So these statements are all legal:

Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()

This example also pointed out another interesting technique: using multiple managers on the same model. You can attach as many Manager() instances to a model as you'd like. This is an easy way to define common "filters" for your models.

For example:

class MaleManager(models.Manager):
def get_query_set(self):
return super(MaleManager, self).get_query_set().filter(sex='M')

class FemaleManager(models.Manager):
def get_query_set(self):
return super(FemaleManager, self).get_query_set().filter(sex='F')

class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female')))
people = models.Manager()
men = MaleManager()
women = FemaleManager()

This example allows you to request Person.men.all(), Person.women.all(), and Person.people.all(), yielding predictable results.

If you use custom Manager objects, take note that the first Manager Django encounters (in order by which they're defined in the model) has a special status. Django interprets the first Manager defined in a class as the "default" Manager. Certain operations -- such as Django's admin site -- use the default Manager to obtain lists of objects, so it's generally a good idea for the first Manager to be relatively unfiltered. In the last example, the people Manager is defined first -- so it's the default Manager.

Model methods

Define custom methods on a model to add custom "row-level" functionality to your objects. Whereas Manager methods are intended to do "table-wide" things, model methods should act on a particular model instance.

This is a valuable technique for keeping business logic in one place -- the model.

For example, this model has a few custom methods:

class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
birth_date = models.DateField()
address = models.CharField(maxlength=100)
city = models.CharField(maxlength=50)
state = models.USStateField() # Yes, this is America-centric...

def baby_boomer_status(self):
"Returns the person's baby-boomer status."
import datetime
if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
return "Baby boomer"
if self.birth_date < datetime.date(1945, 8, 1):
return "Pre-boomer"
return "Post-boomer"

def is_midwestern(self):
"Returns True if this person is from the Midwest."
return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')

def _get_full_name(self):
"Returns the person's full name."
return '%s %s' % (self.first_name, self.last_name)
full_name = property(_get_full_name)

The last method in this example is a property. Read more about properties.

A few object methods have special meaning:

__str__

__str__() is a Python "magic method" that defines what should be returned if you call str() on the object. Django uses str(obj) in a number of places, most notably as the value displayed to render an object in the Django admin site and as the value inserted into a template when it displays an object. Thus, you should always return a nice, human-readable string for the object's __str__. Although this isn't required, it's strongly encouraged.

For example:

class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)

def __str__(self):
return '%s %s' % (self.first_name, self.last_name)

get_absolute_url

Define a get_absolute_url() method to tell Django how to calculate the URL for an object. For example:

def get_absolute_url(self):
return "/people/%i/" % self.id

Django uses this in its admin interface. If an object defines get_absolute_url(), the object-editing page will have a "View on site" link that will jump you directly to the object's public view, according to get_absolute_url().

Also, a couple of other bits of Django, such as the syndication-feed framework, use get_absolute_url() as a convenience to reward people who've defined the method.

It's good practice to use get_absolute_url() in templates, instead of hard-coding your objects' URLs. For example, this template code is bad:

<a href="/people/{{ object.id }}/">{{ object.name }}</a>

But this template code is good:

<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>

(Yes, we know get_absolute_url() couples URLs to models, which violates the DRY principle, because URLs are defined both in a URLconf and in the model. This is a rare case in which we've intentionally violated that principle for the sake of convenience. With that said, we're working on an even cleaner way of specifying URLs in a more DRY fashion.)

Executing custom SQL

Feel free to write custom SQL statements in custom model methods and module-level methods. The object django.db.connection represents the current database connection. To use it, call connection.cursor() to get a cursor object. Then, call cursor.execute(sql, [params]) to execute the SQL and cursor.fetchone() or cursor.fetchall() to return the resulting rows. Example:

def my_custom_sql(self):
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row

connection and cursor simply use the standard Python DB-API. If you're not familiar with the Python DB-API, note that the SQL statement in cursor.execute() uses placeholders, "%s", rather than adding parameters directly within the SQL. If you use this technique, the underlying database library will automatically add quotes and escaping to your parameter(s) as necessary. (Also note that Django expects the "%s" placeholder, not the "?" placeholder, which is used by the SQLite Python bindings. This is for the sake of consistency and sanity.)

A final note: If all you want to do is a custom WHERE clause, you can just just the where, tables and params arguments to the standard lookup API. See Other lookup options.

Overriding default model methods

As explained in the database API docs, each model gets a few methods automatically -- most notably, save() and delete(). You can override these methods to alter behavior.

A classic use-case for overriding the built-in methods is if you want something to happen whenever you save an object. For example:

class Blog(models.Model):
name = models.CharField(maxlength=100)
tagline = models.TextField()

def save(self):
do_something()
super(Blog, self).save() # Call the "real" save() method.
do_something_else()

You can also prevent saving:

class Blog(models.Model):
name = models.CharField(maxlength=100)
tagline = models.TextField()

def save(self):
if self.name == "Yoko Ono's blog":
return # Yoko shall never have her own blog!
else:
super(Blog, self).save() # Call the "real" save() method.

Models across files

It's perfectly OK to relate a model to one from another app. To do this, just import the related model at the top of the model that holds your model. Then, just refer to the other model class wherever needed. For example:

from mysite.geography.models import ZipCode

class Restaurant(models.Model):
# ...
zip_code = models.ForeignKey(ZipCode)

Using models

Once you have created your models, the final step is to tell Django you're going to use those models.

Do this by editing your settings file and changing the INSTALLED_APPS setting to add the name of the module that contains your models.py.

For example, if the models for your application live in the module mysite.myapp.models (the package structure that is created for an application by the manage.py startapp script), INSTALLED_APPS should read, in part:

INSTALLED_APPS = (
#...
'mysite.myapp',
#...
)

Providing initial SQL data

Django provides a hook for passing the database arbitrary SQL that's executed just after the CREATE TABLE statements. Use this hook, for example, if you want to populate default records, or create SQL functions, automatically.

The hook is simple: Django just looks for a file called <appname>/sql/<modelname>.sql, where <appname> is your app directory and <modelname> is the model's name in lowercase.

In the Person example model at the top of this document, assuming it lives in an app called myapp, you could add arbitrary SQL to the file myapp/sql/person.sql. Here's an example of what the file might contain:

INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');

Each SQL file, if given, is expected to contain valid SQL. The SQL files are piped directly into the database after all of the models' table-creation statements have been executed.

The SQL files are read by the sqlinitialdata, sqlreset, sqlall and reset commands in manage.py. Refer to the manage.py documentation for more information.

Note that if you have multiple SQL data files, there's no guarantee of the order in which they're executed. The only thing you can assume is that, by the time your custom data files are executed, all the database tables already will have been created.

Database-backend-specific SQL data

There's also a hook for backend-specific SQL data. For example, you can have separate initial-data files for PostgreSQL and MySQL. For each app, Django looks for a file called <appname>/sql/<modelname>.<backend>.sql, where <appname> is your app directory, <modelname> is the model's name in lowercase and <backend> is the value of DATABASE_ENGINE in your settings file (e.g., postgresql, mysql).

Backend-specific SQL data is executed before non-backend-specific SQL data. For example, if your app contains the files sql/person.sql and sql/person.postgresql.sql and you're installing the app on PostgreSQL, Django will execute the contents of sql/person.postgresql.sql first, then sql/person.sql.

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值