本来是想自己总结教程呢,但是想到有好轮子就直接用的原则使用传送门加个人总结来完成后面内容。
1、模型的初步了解
2、模型进阶了解
3、模型知识点总结
下文适合回顾复习
- 模型
模型准确且唯一的描述了数据。它包含您储存的数据的重要字段和行为。一般来说,每一个模型都映射一张数据库表。- 基础:
- 每个模型都是一个 Python 的类,这些类继承
- 模型类的每个属性都相当于一个数据库的字段。
- 使用模型
你需要修改设置文件中的 在这个设置中添加包含 models.py 文件的模块名称。- INSTALLED_APPS = [ #... 'myapp', #...]
- 当你向 [INSTALLED_APPS] 添加新的应用的时候,请务必运行使用以下命令进行迁移
- manage.py makemigrations
- manage.py migrate
- 字段和字段选项(参考#模型字段pdf)
模型中最重要且唯一必要的是数据库的字段定义。字段在类属性中定义。定义字段名时应小心避免使用与 模型 API冲突的名称, 如 clean, save, or delete 等.- 命名限制
- 一个字段的名称不能是 Python 保留字,因为这会导致 Python 语法错误
- 一个字段名称不能包含连续的多个下划线,原因在于 Django 查询语法的工作方式。
- 字段名不能以下划线结尾,原因同上
- SQL保留字,例如 join, where 或 select
- 可创建自己模型字段
- 命名限制
- 主键(每个模型所必须的)
- 默认情况下, Django 会给每一个模型添加下面的字段:
- id = models.AutoField(primary_key=True)
- 如果你想自己指定主键, 在你想要设置为主键的字段上设置参数 primary_key=True
- 字段关联
- 一对一
- OneToOneField(on_delete=models.CASCADE,)
- 一对多
- 级联删除:ForeignKey(on_delete=models.CASCADE)
- 设置为空:ForeignKey(on_delete=models.SET_NULL,null=True,blank=True)
- 多对多
- ManyToManyField
- 显示声明在一个模型使用两个一对多外键
- 反向查询
- 对象名_set
- 使用related_name
- on_delete选项
- (1)、on_delete = None:
- 删除关联表的数据时,当前表与关联表的filed的行为。
- (2)、on_delete = models.CASCADE:
- 表示级联删除,当关联表(子表)中的数据删除时,与其相对应的外键(父表)中的数据也删除。
- (3)、on_delete = models.DO_NOTHING:
- 你删你的,父亲(外键)不想管你
- (4)、on_delete = models.PROTECT:
- 保护模式,如采用这个方法,在删除关联数据时会抛出ProtectError错误
- (5)、on_delete = models.SET_DEFAULT:
- 设置默认值,删除子表字段时,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
- (6)、on_delete = models.SET(值):
- 删除关联数据时,自定义一个值,该值只能是对应指定的实体
- 一对一
- Meta选项
- abstract
这个属性是定义当前的模型是不是一个抽象类。所谓抽象类是不会对应数据库表的。一般我们用它来归纳一些公共属性字段,然后继承它的子类可以继承这些字段。
- Options.abstract
如果abstract = True 这个model就是一个抽象类
- app_label
这个选型只在一种情况下使用,就是你的模型不在默认的应用程序包下的models.py文件中,这时候需要指定你这个模型是哪个应用程序的。
- Options.app_label
如果一个model定义在默认的models.py,例如如果你的app的models在myapp.models子模块下,你必须定义app_label让Django知道它属于哪一个app
app_label = 'myapp'
- db_table
db_table是指定自定义数据库表明的。Django有一套默认的按照一定规则生成数据模型对应的数据库表明。
Options.db_table
定义该model在数据库中的表名称
db_table = 'Students'
如果你想使用自定义的表名,可以通过以下该属性
table_name = 'my_owner_table'
数据表名称
Django 会根据模型类的名称和包含它的应用的名称自动指定数据库表名称。一个模型的数据库表名称,由这个模型的“应用标签”(在manage.py startapp中使用的名称)和模型类名称之间加上下划线组成。
举个例子, bookstore应用(使用 manage.py startapp bookstore 创建),里面有个名为 Book的模型,那数据表的名称就是 bookstore_book 。
使用 Meta类中的 db_table 参数来重写数据表的名称。
数据表名称可以是 SQL 保留字,也可以包含不允许出现在 Python 变量中的特殊字符,这是因为 Django 会自动给列名和表名添加引号。
在 MySQL中使用小写字母为表命名
当你通过db_table覆写表名称时,强烈推荐使用小写字母给表命名,特别是如果你用了MySQL作为后端。
Oracle中表名称的引号处理
为了遵从Oracle中30个字符的限制,以及一些常见的约定,Django会缩短表的名称,而且会把它全部转为大写。在db_table的值外面加上引号来避免这种情况:
db_table = '"name_left_in_lowercase"'
这种带引号的名称也可以用于Django所支持的其他数据库后端,但是除了Oracle,引号不起任何作用。
- db_teblespace
定义这个model所使用的数据库表空间。如果在项目的settin中定义那么它会使用这个值
- default_related_name
这个名字会默认被用于一个关联对象到当前对象的关系。默认为 _set。
由于一个字段的反转名称应该是唯一的,当你给你的模型设计子类时,要格外小心。为了规避名称冲突,名称的一部分应该含有'%(app_label)s'和'%(model_name)s',它们会被应用标签的名称和模型的名称替换,二者都是小写的。
- get_latest_by
- Options.get_latest_by
- 在model中指定一个DateField或者DateTimeField。这个设置让你在使用model的Manager上的lastest方法时,默认使用指定字段来排序
- managed
该参数不设置的时候,默认为 True。
如果为 True,那么对这个 model 的每次更改,都会在 makemigrations 的时候被检测到。
这个字段如果为 False,表示 Django 在 makemigrations 的时候会忽略检测这张表,常用在仅用于系统查询的表。
- order_with_respect_to
这个选项一般用于多对多的关系中,它指向一个关联对象,就是说关联对象找到这个对象后它是经过排序的。指定这个属性后你会得到一个get_xxx_order()和set_xxx_order()的方法,通过它们你可以设置或者回去排序的对象
- ordering
这个字段是告诉Django模型对象返回的记录结果集是按照哪个字段排序的。这是一个字符串的元组或列表,没有一个字符串都是一个字段和用一个可选的表明降序的'-'构成。当字段名前面没有'-'时,将默认使用升序排列。使用'?'将会随机排列
ordering=['order_date'] # 按订单升序排列
ordering=['-order_date'] # 按订单降序排列,-表示降序
ordering=['?order_date'] # 随机排序,?表示随机
ordering=['-pub_date','author'] # 以pub_date为降序,在以author升序排列
- permissions
permissions主要是为了在Django Admin管理模块下使用的,如果你设置了这个属性可以让指定的方法权限描述更清晰可读。Django自动为每个设置了admin的对象创建添加,删除和修改的权限。
permissions = (('can_deliver_pizzas','Can deliver pizzas'))
- proxy
这是为了实现代理模型使用的,如果proxy = True,表示model是其父的代理 model
- unique_together
unique_together这个选项用于:当你需要通过两个字段保持唯一性时使用。比如假设你希望,一个Person的FirstName和LastName两者的组合必须是唯一的,那么需要这样设置:
unique_together = (("first_name", "last_name"),)
一个ManyToManyField不能包含在unique_together中。如果你需要验证关联到ManyToManyField字段的唯一验证,尝试使用signal(信号)或者明确指定through属性。
- verbose_name
verbose_name的意思很简单,就是给你的模型类起一个更可读的名字一般定义为中文,我们:
verbose_name = "学校"
- verbose_name_plural
这个选项是指定,模型的复数形式是什么,比如:
verbose_name_plural = "学校"
如果不指定Django会自动在模型名称后加一个’s’
- abstract
- 模型方法
一般通过 模型.objects.xxxx() 调用- 自带方法
- __str__()方法:返回模型名称
- get_XXX_display方法:获取对象的choice选项值
- save()方法
def save(self, args, **kwargs):
self.fields = 1
super().save(*args, *kwargs)
- delete()方法,同上
- 重写方法
- 自定义方法
- 自带方法
- 抽象基类
抽象基类在你要将公共信息放入很多模型时会很有用。编写你的基类,并在 [Meta]类中填入 abstract=True。该模型将不会创建任何数据表。当其用作其它模型类的基类时,它的字段会自动添加至子类。
- 代理模型
使用 [多表继承](#multi-table-inheritance) 时,每个子类模型都会创建一张新表。这一般是期望的行为,因为子类需要一个地方存储基类中不存在的额外数据字段。不过,有时候你只想修改模型的 Python 级行为——可能是修改默认管理器,或添加一个方法。
这是代理模型继承的目的:为原模型创建一个 代理。你可以创建,删除和更新代理模型的实例,所以的数据都会存储的像你使用原模型(未代理的)一样。不同点是你可以修改代理默认的模型排序和默认管理器,而不需要修改原模型。
class Meta:
proxy = True
- 同一包内管理模型
- [manage.py startapp] 命令创建了一个应用结构,包含一个 models.py 文件。若你有很多 models.py 文件,用独立的文件管理它们会很实用。
- 为了达到此目的,创建一个 models 包。删除 models.py,创建一个 myapp/models 目录,包含一个 __init__.py 文件和存储模型的文件。你必须在 __init__.py 文件中导入这些模块。
- 比如,若你在 models 目录下有 organic.py 和 synthetic.py:
- myapp/models/init.py下:from .organic import Person from .synthetic import Robot
- 基础: