模型元数据是“任何不是字段的数据”,比如排序选项(ordering),数据库表名(db_table)或者人类可读的单复数名称(verbose_name 和verbose_name_plural)。在模型中添加class Meta是完全可选的,所有选项都不是必须的。

class Book(models.Model):
name =models.CharField(max_length=32) def __str__(self):
return self.name class Author(models.Model):
name = models.CharField(max_length=32)
m = models.ManyToManyField('Book') def __str__(self):
return self.name class A_to_B(models.Model):
bid = models.ForeignKey(Book)
aid = models.ForeignKey(Author) class Meta:
unique_together = (
('bid','aid'),
)

  上面定义了2张表,一张是Book表,一张是Author表,然后定义了一个多对多关系的A_to_B表,最后定义了元数据,它的意思上面的多对多表具有唯一约束。

可用的元选项

1、abstract

这个属性是定义当前的模型类是不是一个抽象类。所谓抽象类是不会相应数据库表的。一般我们用它来归纳一些公共属性字段,然后继承它的子类能够继承这些字段。

比方以下的代码中Human是一个抽象类。Employee是一个继承了Human的子类,那么在执行syncdb命令时,不会生成Human表。可是会生成一个Employee表,它包括了Human中继承来的字段。以后假设再加入一个Customer模型类,它能够相同继承Human的公共属性:

class Human(models.Model):
name=models.CharField(max_length=100)
GENDER_CHOICE=((u'M',u'Male'),(u'F',u'Female'),)
gender=models.CharField(max_length=2,choices=GENDER_CHOICE,null=True)
class Meta:
abstract=True
class Employee(Human):
joint_date=models.DateField()
class Customer(Human):
first_name=models.CharField(max_length=100)
birth_day=models.DateField()

  上面的代码,运行python manage.py syncdb 后的输出结果入下。能够看出Human表并没有被创建:

$ python manage.py syncdb
Creating tables ...
Creating table myapp_employee
Creating table myapp_customer
Installing custom SQL ...
Installing indexes ...
No fixtures found.

  

2、app_label

Options.app_label
如果一个模型位于标准的位置之外(应用的models.py 或models 包),该模型必须定义它属于哪个应用:

app_label = 'myapp'
New in Django 1.7:
定义在应用的models 模块以外的模型,不再需要app_label。

3、db_table

Options.db_table
该模型所用的数据表的名称:

db_table = 'music_album'
为节省你的时间,Django 会根据模型类的名称和包含它的应用的名称自动指定数据库表名称。一个模型的数据库表名称,由这个模型的“应用标签”(在manage.py startapp中使用的名称)和模型类名称之间加上下划线组成。

举个例子,  bookstore应用(使用  manage.py startapp bookstore 创建),里面有个名为 Book的模型,那数据表的名称就是  bookstore_book 。

使用 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 注意事项 。

4、db_tablespace

Options.db_tablespace
当前模型所使用的数据库表空间 的名字。默认值是项目设置中的DEFAULT_TABLESPACE,如果它存在的话。如果后端并不支持表空间,这个选项可以忽略。

5、default_related_name

Options.default_related_name
New in Django 1.8.
这个名字会默认被用于一个关联对象到当前对象的关系。默认为 <model_name>_set。

由于一个字段的反转名称应该是唯一的,当你给你的模型设计子类时,要格外小心。为了规避名称冲突,名称的一部分应该含有'%(app_label)s'和'%(model_name)s',它们会被应用标签的名称和模型的名称替换,二者都是小写的。详见抽象模型的关联名称。

6、get_latest_by

Options.get_latest_by
模型中某个可排序的字段的名称,比如DateField、DateTimeField或者IntegerField。它指定了Manager的latest()和earliest()中使用的默认字段。

例如:

get_latest_by = "order_date"
详见latest() 文档。

7、managed

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

如果是False,Django 就不会为当前模型创建和删除数据表。如果当前模型表示一个已经存在的,通过其它方法建立的数据库视图或者数据表,这会相当有用。这是设置为managed=False时唯一的不同之处。. 模型处理的其它任何方面都和平常一样。这包括:

如果你不声明它的话,会向你的模型中添加一个自增主键。为了避免给后面的代码读者带来混乱,强烈推荐你在使用未被管理的模型时,指定数据表中所有的列。

如果一个带有managed=False的模型含有指向其他未被管理模型的ManyToManyField,那么多对多连接的中介表也不会被创建。但是,一个被管理模型和一个未被管理模型之间的中介表会被创建。

如果你需要修改这一默认行为,创建中介表作为显式的模型(设置为managed),并且使用ManyToManyField.through为你的自定义模型创建关联。

对于带有managed=False的模型的测试,你要确保在测试启动时建立正确的表。

如果你对修改模型类在Python层面的行为感兴趣,你可以设置 managed=False ,并且为一个已经存在的模型创建一个副本。但是这种情况下使用代理模型才是更好的方法。

8、order_with_respect_to

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属性,要确保执行和应用了合适的迁移操作。

9、ordering

Options.ordering
对象默认的顺序,获取一个对象的列表时使用:

ordering = ['-order_date']
它是一个字符串的列表或元组。每个字符串是一个字段名,前面带有可选的“-”前缀表示倒序。前面没有“-”的字段表示正序。使用"?"来表示随机排序。

例如,要按照pub_date字段的正序排序,这样写:

ordering = ['pub_date']
按照pub_date字段的倒序排序,这样写:

ordering = ['-pub_date']
先按照pub_date的倒序排序,再按照 author 的正序排序,这样写:

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

排序并不是没有任何代价的操作。你向ordering属性添加的每个字段都会产生你数据库的开销。你添加的每个外键也会隐式包含它的默认顺序。

10、permissions

Options.permissions
设置创建对象时权限表中额外的权限。增加、删除和修改权限会自动为每个模型创建。这个例子指定了一种额外的权限,can_deliver_pizzas:

permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
它是一个包含二元组的元组或者列表,格式为 (permission_code, human_readable_permission_name)。

11、default_permissions

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

12、proxy

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

13、select_on_save

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()。

14、unique_together

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异常。

15、index_together

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

index_together = [
    ["pub_date", "deadline"],
]
列表中的字段将会建立索引(例如,会在CREATE INDEX语句中被使用)。

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

index_together = ["pub_date", "deadline"]

16、verbose_name

Options.verbose_name
对象的一个易于理解的名称,为单数:

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

17、verbose_name_plural

Options.verbose_name_plural
该对象复数形式的名称:

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

Django之Models的class Meta的更多相关文章

  1. 【Django】--Models 和ORM以及admin配置

    Models 数据库的配置 1    django默认支持sqlite,mysql, oracle,postgresql数据库 <1>sqlite django默认使用sqlite的数据库 ...

  2. Django的Models

    Django的数据库配置: 1    django默认支持sqlite,mysql, oracle,postgresql数据库 2.   在django的项目中会默认使用sqlite数据库,如果要使用 ...

  3. Django的models实现分析

    1      引子 1.1     神奇的Django中的models 我们先来看一段在Django项目中常用的代码: 设置数据库models代码: class Students(models.Mod ...

  4. django的models模型类的常用数据类型和选项

    django框架的models模块ORM框架,能够让我们通过编写类的方式,帮助我们自动生成数据库表. 生成的数据库表名为 应用模块名称_类名 数据库表中字段名 如果我们没有在参数中指定,就是我们写的类 ...

  5. Django之Models操作

    一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 pr ...

  6. Django之Models(一)

    Django之Models(一) 目录 数据库的配置 模型代码与参数解析 ORM对单表的增删改查 查询的补充 数据库配置 django默认支持sqlite,mysql, oracle,postgres ...

  7. Django之Models进阶操作(字段属性)

    字段属性详细介绍 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列, ...

  8. Django model 中的 class Meta 详解

    Django model 中的 class Meta 详解 通过一个内嵌类 "class Meta" 给你的 model 定义元数据, 类似下面这样: class Foo(mode ...

  9. Django之Models与ORM操作

    一.models例子 from django.db import models class User(models.Model): """ 用户表 "" ...

随机推荐

  1. 【[国家集训队]Crash的数字表格 / JZPTAB】

    这道题我们要求的是 \[\sum_{i=1}^N\sum_{j=1}^Mlcm(i,j)\] 总所周知\(lcm\)的性质不如\(gcd\)优雅,但是唯一分解定理告诉我们\(gcd(i,j)\time ...

  2. 7、Spring -Cloud-路由网管Spring Cloud Zuul

    7.1.为什么需要Zuul Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用: 7.2.Zuul的工作原理 Zuul 是通过 Servlet 来实现的, Zuul 通过自定义的 Zuu!S ...

  3. Owin+ASP.NET Identity浅析系列(四)实现用户角色

    在今天,读书有时是件“麻烦”事.它需要你付出时间,付出精力,还要付出一份心境.--仅以<Owin+ASP.NET Identity浅析系列>来祭奠那逝去的…… 通过Owin+ASP.NET ...

  4. js apply的用法

    问题: 1.apply和call的区别在哪里 2.什么情况下用apply,什么情况下用call 3.apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和ca ...

  5. linux下批量重命名文件

    # 使用通配符批量创建 多个文件:$ touch zqunor{1..7}.txt # 批量将多个后缀为 .txt 的文本文件重命名为以 .c 为后缀的文件:$ rename 's/\.txt/\.c ...

  6. jenkins持续集成工作原理

    转载https://www.cnblogs.com/liyuanhong/p/6548925.html 片段 这里是选择Gitlab作为git server.Gitlab的功能和Github差不多,但 ...

  7. PL/SQL Developer修改窗口字体和大小

    工具 → 首选项 → 字体 → 选择, 然后自己调节设置

  8. PAT——1057. 数零壹

    给定一串长度不超过105的字符串,本题要求你将其中所有英文字母的序号(字母a-z对应序号1-26,不分大小写)相加,得到整数N,然后再分析一下N的二进制表示中有多少0.多少1.例如给定字符串“PAT ...

  9. [LuoguP2158][SDOI2008]仪仗队

    [LuoguP2158][SDOI2008]仪仗队(Link) 现在你有一个\(N \times N\)的矩阵,求你站在\((1,1)\)点能看到的点的总数. 很简洁的题面. 这道题看起来很难,但是稍 ...

  10. 网络测量中基于Sketch方法的调查

    目录 LD Sketch SeqHash What's New reversible sketch Count-Sketch和Count-min sketch Diamond Sketch: Accu ...