Django 模型层 Meta 选项详解

Meta 是 Django 模型类的一个内部类,用于定义一些与 Django 特定模型相关的一些选项。

可选的选项有

1. abstract

表示模型是否是抽象基类,abstract = True,则表示模型是抽象基类。
所谓抽象基类,指该模型不会对应数据库表,即 Django 不会在数据库中为该模型创建表。一般情况下,我们使用抽象基类来定义一组公共属性的字段,其他需要使用这组字段的模型只要直接继承这个抽象类就可以拥有该组字段。

2. app_label

如果模型类不在应用程序的 model.py 下,而是来自其他应用程序,则必须要指定 app_label。
如:

app_label = 'other_app'

3. db_table

该模型所用的数据库表的名称:

db_table = 'myapp'

关于数据库表名称:
默认情况下,Django 会按一定规则为模型类自动指定数据库表名称,名称由模型的“应用标签”(在manage.py startapp中使用的名称)和模型类名称之间加上下划线组成,如:myapp_model1
如果想使用自定义的表名,就需要通过 db_table 属性指定。

4. db_tablespace

有些数据库有数据库表空间,比如 Oracle。可以通过 db_tablespace 来指定这个模型对应的数据库表放在哪个数据库表空间。
默认值是项目设置中 的 DEFAULT_TABLESPAC。
如果数据库并不支持表空间,这个选项可以忽略。

5. related_name

关联对象反向引用的标识,默认为:<model_name>_set。
假设有两个 model,分别为 Book 和 Author,其中 Book 模型有指向 Author 的外键:

class Book(models.Model):
    author = models.ForeignKey(Author)

那么,Author 可以通过 book_set 关联到 Book。
通过 related_name 可以修改这个标识。

6. get_latest_by

Django Manager 的 latest() 和 earliest() 可以得到最近一行的记录,get_latest_by 可以指定它们使用的默认字段。
get_latest_by 的值必须是模型中某个可排序的字段的名称,比如DateField、DateTimeField 或者 IntegerField。

7. managed

默认为 True,意思是 Django 会在 migrate 命令中为模型创建合适的数据表,并且会在 flush 管理命令中移除它们。换句话说,Django 会管理这些数据表的生命周期。

如果是 False,Django 就不会为当前模型创建和删除数据表。如果当前模型表示一个已经存在的,通过其它方法建立的数据库视图或者数据表,这会相当有用。

8. 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,所以如果你在首次迁移之后添加或者修改了order_with_respect_to 属性,要确保执行和应用了合适的迁移操作。

9. ordering

表示使用 Django 的数据库 API 检索时,返回的结果按照哪个字段进行排序。
ordering 的值是一个字符串的列表或者元组,每个字符串表示一个字段名。
ordering 支持升序排序,倒叙排序和随机排序

  1. ordering = ['created_date'] 表示按 created_date 升序排序
  2. ordering = ['-created_date'] 表示按 created_date 倒序排序
  3. ordering = ['?created_date'] 表示随机排序

如果 ordering 的值是一个元组,则结果按元组里元素的顺序进行排序,例如:
ordering = ['publish_date','-created_date']
表示结果先按 publish_date 升序排序,再按 created_date 倒序排序,依此类推。
警告:
排序并不是没有任何代价的操作。你向 ordering 属性添加的每个字段都会产生你数据库的开销,你添加的每个外键也会隐式包含它的默认顺序。

10. permissions

主要是为了在 Django Admin 管理模块下使用的。
表示创建对象时权限表中额外的权限。增加、删除和修改权限会自动为每个模型创建。
可以为模型指定其他的权限:

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

这个例子指定了一种额外的权限,can_deliver_pizzas。
它是一个包含二元组的元组或者列表,格式为 (permission_code, human_readable_permission_name)。

11. default_permissions

New in Django 1.7.
默认为('add', 'change', 'delete')。你可以自定义这个列表,比如,如果你的应用不需要默认权限中的任何一项,可以把它设置成空列表。在模型被 migrate 命令创建之前,这个属性必须被指定,以防一些遗漏的属性被创建。

12. proxy

如果 proxy = True, 它作为另一个模型的子类,将会作为一个代理模型。

13. unique_together

当需要通过两个字段保持模型唯一性时使用。
假设有一个 User 类,我们希望 User 的 username 和 email 两个属性的组合必须是唯一的,那么需要设置为:

unique_together = (("username", "email"),)

unique_together 的值是一个元组的元组。为了方便起见,处理单一字段的集合时,unique_together 可以是一维的元组,如:

unique_together = ("driver", "restaurant")

ManyToManyField 不能包含在 unique_together 中。如果你需要验证ManyToManyField 关联的唯一性,试着使用信号或者显式的贯穿模型(explicit through model)。

Changed in Django 1.7:
当 unique_together 的约束被违反时,模型校验期间会抛出ValidationError 异常。

14. index_together

用来设置带有索引的字段组合:

index_together = [
    ["pub_date", "deadline"],
]

列表中的字段将会建立索引(例如,会在CREATE INDEX语句中被使用)。

Changed in Django 1.7.
为了方便起见,处理单一字段的集合时,index_together 可以是一个一维的列表。

index_together = ["pub_date", "deadline"]

15. verbose_name

为模型指定一个更可读的名称,为单数。

verbose_name = "book"

如果此项没有设置,Django 会把类名拆分开来作为自述名,比如CamelCase 会变成 camel case,

16. verbose_name_plural

模型复数形式的名称:

verbose_name_plural = "books"

如果此项没有设置,Django 会使 用 verbose_name + "s"。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容