使用内部的class Meta 定义模型的元数据,例如:python
from django.db import models class Ox(models.Model): horn_length = models.IntegerField() class Meta: ordering = ["horn_length"] verbose_name_plural = "oxen"
模型元数据是“任何不是字段的数据”,好比排序选项(ordering),数据库表名(db_table)或者人类可读的单复数名称(verbose_name 和verbose_name_plural)。在模型中添加class Meta是彻底可选的,全部选项都不是必须的。算法
Options.abstract
若是 abstract = True, 就表示模型是 抽象基类 (abstract base class).数据库
Options.app_label
若是一个模型位于标准的位置以外(应用的models.py 或models 包),该模型必须定义它属于哪一个应用:django
app_label = 'myapp'
New in Django 1.7:
定义在应用的models 模块之外的模型,再也不须要app_label。后端
Options.db_table
该模型所用的数据表的名称:app
db_table = 'music_album'
为节省你的时间,Django 会根据模型类的名称和包含它的应用的名称自动指定数据库表名称。一个模型的数据库表名称,由这个模型的“应用标签”(在manage.py startapp中使用的名称)和模型类名称之间加上下划线组成。测试
举个例子, bookstore应用(使用 manage.py startapp bookstore 建立),里面有个名为 Book的模型,那数据表的名称就是 bookstore_book 。spa
使用 Meta类中的 db_table 参数来重写数据表的名称。设计
数据表名称能够是 SQL 保留字,也能够包含不容许出如今 Python 变量中的特殊字符,这是由于 Django 会自动给列名和表名添加引号。代理
在 MySQL中使用小写字母为表命名
当你经过db_table覆写表名称时,强烈推荐使用小写字母给表命名,特别是若是你用了MySQL做为后端。详见MySQL注意事项 。
Oracle中表名称的引号处理
为了听从Oracle中30个字符的限制,以及一些常见的约定,Django会缩短表的名称,并且会把它所有转为大写。在db_table的值外面加上引号来避免这种状况:
db_table = '"name_left_in_lowercase"'
这种带引号的名称也能够用于Django所支持的其余数据库后端,可是除了Oracle,引号不起任何做用。详见 Oracle 注意事项 。
Options.db_tablespace
当前模型所使用的数据库表空间 的名字。默认值是项目设置中的DEFAULT_TABLESPACE,若是它存在的话。若是后端并不支持表空间,这个选项能够忽略。
Options.default_related_name
New in Django 1.8.
这个名字会默认被用于一个关联对象到当前对象的关系。默认为 <model_name>_set。
因为一个字段的反转名称应该是惟一的,当你给你的模型设计子类时,要格外当心。为了规避名称冲突,名称的一部分应该含有'%(app_label)s'和'%(model_name)s',它们会被应用标签的名称和模型的名称替换,两者都是小写的。详见抽象模型的关联名称。
Options.get_latest_by
模型中某个可排序的字段的名称,好比DateField、DateTimeField或者IntegerField。它指定了Manager的latest()和earliest()中使用的默认字段。
例如:
get_latest_by = "order_date"
详见latest() 文档。
Options.managed
默认为True,意思是Django在migrate命令中建立合适的数据表,而且会在 flush 管理命令中移除它们。换句话说,Django会管理这些数据表的生命周期。
若是是False,Django 就不会为当前模型建立和删除数据表。若是当前模型表示一个已经存在的,经过其它方法创建的数据库视图或者数据表,这会至关有用。这是设置为managed=False时惟一的不一样之处。. 模型处理的其它任何方面都和日常同样。这包括:
若是你不声明它的话,会向你的模型中添加一个自增主键。为了不给后面的代码读者带来混乱,强烈推荐你在使用未被管理的模型时,指定数据表中全部的列。
若是一个带有managed=False的模型含有指向其余未被管理模型的ManyToManyField,那么多对多链接的中介表也不会被建立。可是,一个被管理模型和一个未被管理模型之间的中介表会被建立。
若是你须要修改这一默认行为,建立中介表做为显式的模型(设置为managed),而且使用ManyToManyField.through为你的自定义模型建立关联。
对于带有managed=False的模型的测试,你要确保在测试启动时创建正确的表。
若是你对修改模型类在Python层面的行为感兴趣,你能够设置 managed=False ,而且为一个已经存在的模型建立一个副本。可是这种状况下使用代理模型才是更好的方法。
Options.order_with_respect_to
按照给定的字段把这个对象标记为”可排序的“。这一属性一般用到关联对象上面,使它在父对象中有序。好比,若是Answer和 Question相关联,一个问题有至少一个答案,而且答案的顺序很是重要,你能够这样作:
from django.db import models class Question(models.Model): text = models.TextField() # ... class Answer(models.Model): question = models.ForeignKey(Question) # ... class Meta: order_with_respect_to = 'question'
当order_with_respect_to 设置以后,模型会提供两个用于设置和获取关联对象顺序的方法:get_RELATED_order() 和set_RELATED_order(),其中RELATED是小写的模型名称。例如,假设一个 Question 对象有不少相关联的Answer对象,返回的列表中含有与之相关联Answer对象的主键:
>>> question = Question.objects.get(id=1) >>> question.get_answer_order() [1, 2, 3]
与Question对象相关联的Answer对象的顺序,能够经过传入一格包含Answer 主键的列表来设置:
>>> question.set_answer_order([3, 1, 2])
相关联的对象也有两个方法, get_next_in_order() 和get_previous_in_order(),用于按照合适的顺序访问它们。假设Answer对象按照 id来排序:
>>> answer = Answer.objects.get(id=2) >>> answer.get_next_in_order() <Answer: 3> >>> answer.get_previous_in_order() <Answer: 1>
修改 order_with_respect_to
order_with_respect_to属性会添加一个额外的字段(/数据表中的列)叫作_order,因此若是你在首次迁移以后添加或者修改了order_with_respect_to属性,要确保执行和应用了合适的迁移操做。
Options.ordering
对象默认的顺序,获取一个对象的列表时使用:
ordering = ['-order_date']
它是一个字符串的列表或元组。每一个字符串是一个字段名,前面带有可选的“-”前缀表示倒序。前面没有“-”的字段表示正序。使用"?"来表示随机排序。
例如,要按照pub_date字段的正序排序,这样写:
ordering = ['pub_date']
按照pub_date字段的倒序排序,这样写:
ordering = ['-pub_date']
先按照pub_date的倒序排序,再按照 author 的正序排序,这样写:
ordering = ['-pub_date', 'author']
警告
排序并非没有任何代价的操做。你向ordering属性添加的每一个字段都会产生你数据库的开销。你添加的每一个外键也会隐式包含它的默认顺序。
Options.permissions
设置建立对象时权限表中额外的权限。增长、删除和修改权限会自动为每一个模型建立。这个例子指定了一种额外的权限,can_deliver_pizzas:
permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
它是一个包含二元组的元组或者列表,格式为 (permission_code, human_readable_permission_name)。
Options.default_permissions
New in Django 1.7.
默认为('add', 'change', 'delete')。你能够自定义这个列表,好比,若是你的应用不须要默认权限中的任何一项,能够把它设置成空列表。在模型被migrate命令建立以前,这个属性必须被指定,以防一些遗漏的属性被建立。
Options.proxy
若是proxy = True, 它做为另外一个模型的子类,将会做为一个代理模型。
Options.select_on_save
该选项决定了Django是否采用1.6以前的 django.db.models.Model.save()算法。旧的算法使用SELECT来判断是否存在须要更新的行。而新式的算法直接尝试使用 UPDATE。在一些小几率的状况中,一个已存在的行的UPDATE操做并不对Django可见。好比PostgreSQL的ON UPDATE触发器会返回NULL。这种状况下,新式的算法会在最后执行 INSERT 操做,即便这一行已经在数据库中存在。
一般这个属性不须要设置。默认为False。
关于旧式和新式两种算法,请参见django.db.models.Model.save()。
Options.unique_together
用来设置的不重复的字段组合:
unique_together = (("driver", "restaurant"),)
它是一个元组的元组,组合起来的时候必须是惟一的。它在Django后台中被使用,在数据库层上约束数据(好比,在 CREATE TABLE 语句中包含 UNIQUE语句)。
为了方便起见,处理单一字段的集合时,unique_together 能够是一维的元组:
unique_together = ("driver", "restaurant")
ManyToManyField不能包含在unique_together中。(这意味着什么并不清楚!)若是你须要验证ManyToManyField关联的惟一性,试着使用信号或者显式的贯穿模型(explicit through model)。
Changed in Django 1.7:
当unique_together的约束被违反时,模型校验期间会抛出ValidationError异常。
Options.index_together
用来设置带有索引的字段组合:
index_together = [
["pub_date", "deadline"],
]
列表中的字段将会创建索引(例如,会在CREATE INDEX语句中被使用)。
Changed in Django 1.7.
为了方便起见,处理单一字段的集合时,index_together能够是一个一维的列表。
index_together = ["pub_date", "deadline"]
Options.verbose_name
对象的一个易于理解的名称,为单数:
verbose_name = "pizza"
若是此项没有设置,Django会把类名拆分开来做为自述名,好比CamelCase 会变成camel case,
Options.verbose_name_plural
该对象复数形式的名称:
verbose_name_plural = "stories" 若是此项没有设置,Django 会使用 verbose_name + "s"。