字段
一、ORM字段与参数
AutoField
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField
一个整数类型,范围在 -2147483648 to 2147483647。
CharField
字符类型,必须提供max_length参数, max_length表示字符长度。
DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
常用字段
1. AutoField():默认自增主键(primary_key=True),int自增列,django会默认建立id字段主键
2. BooleanField():布尔字段,对应数据库tinyint类型
3. CharField():字符类型
-- 字段属性max_length=64,数据长度,必须明确
4. DateField():年月日时间类型
-- 字段属性auto_now=True,数据被更新就会更新时间
-- 字段属性auto_now_add=True,数据第一次参数时产生
5. DateTimeField():年月日小时分钟秒时间类型
-- 字段属性auto_now=True,数据被更新就会更新时间
-- 字段属性auto_now_add=True,数据第一次参数时产生
6. DecimalField():混合精度的小数类型
-- 字段属性max_digits=3,限定数字的最大位数(包含小数位)
-- 字段属性decimal_places=2,限制小数的最大位数
7. IntegerField():整型
常用字段共有属性参数
1. null:默认为False,True表示字段可为null
2. blank:默认为False,True表示字段可为空
3. choice:可选的,限制了该选项的字段值必须是所指定的choice中的一个:
-- sex = models.SmallIntegerField(choices=((1, '男'), (2, "女")))
-- obj.get_sex_display()
4. db_column:自定义字段名
5. db_index:如果为True的话,设置索引
6. default:字段默认值
7. editable:默认为True,若为False,则不会在/admin/界面显示
8. primary_key:若设置为True,则表示将该字段设置为主键。一般情况下django默认会设置一个自增长的id主键。
9. unique:若设置为True,该字段值不可重复
10。DateField与DateTimeField:
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库
配置上auto_now=True,每次更新数据记录的时候会更新该字段
不常用字段
1. BigAutoField():大整型自增
--bigint自增列,必须填入参数prinmary_key = True
2. BigIntegerField():长整型
-- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
3.SmallIntegerField(IntegerField):
-- 小整数 -32768 ~ 32767
4.PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
-- 正小整数 0 ~ 32767
5.IntegerField(Field)
-- 整数列(有符号的) -2147483648 ~ 2147483647
6.PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
-- 正整数 0 ~ 2147483647
7.NullBooleanField(Field):
-- 可以为空的布尔值
8.FilePathField(Field)
-- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
-- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
9.FileField(Field):文件字段
-- 字符串,路径保存在数据库,文件上传到指定目录
-- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认
10. EmailField():邮箱字段,拥有/admin/验证
11. FloatField():浮点型小数
12. TextField():大文本类型
ORM字段与数据库实际对应关系
对应关系:
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)',
二、关系字段
1、ForeignKey()
外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。
ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系
ForeignKey():外键字段
-- 字段属性to关联模型类
-- 字段属性to_field关联字段,省略默认关联主键
-- 字段属性on_delete (外键关联数据被删除时的操作)
-- models.CASCADE 级联删除
-- modles.PROTECT 抛出异常
-- models.SET_NULL 设置空值
-- models.SET_DEFAULT 设置默认值
-- models.SET(value)自定义值
-- 字段属性related_name,反向操作时,自定义反向查询的字段名,用于代替反向查询时的'表名_set'
-- 字段属性db_constraint=False取消关联关系,但还可以使用连表查询
总结:models.ForeignKey(to='关联的类名', null=True, on_delete=models.SET_NULL, db_constraint=False, related_name="本类名小写")
on_delete#(在Django2.0 环境下需要明确 on delete 属性)
当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE:删除关联数据,与之关联也删除
models.DO_NOTHING:删除关联数据,引发错误IntegrityError
models.PROTECT:删除关联数据,引发错误ProtectedError
models.SET_NULL:删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT:删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
models.SET:删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象
2、OneToOneField
一对一字段通常
一对一字段用来扩展已有字段。
一对一的关联关系多用在当一张表的不同字段查询频次差距过大的情况下,将本可以存储在一张表的字段拆开放置在两张表中,然后将两张表建立一对一的关联关系。
(同Foreignkey)-- 字段属性to关联模型类
-- 字段属性to_field关联字段,省略默认关联主键
-- 字段属性on_delete (外键关联数据被删除时的操作)
-- models.CASCADE 级联删除
-- modles.PROTECT 抛出异常
-- models.SET_NULL 设置空值
-- models.SET_DEFAULT 设置默认值
-- models.SET(value)自定义值
3、ManyToManyField()多对多关系字段
-- 字段属性to 同ForeignKey
--symmetrical:仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。
-- 字段属性through关联关系类,在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。
-- 字段属性through_fields关联关系表中(本身类名小写字段, 关联表类名小写字段)
--da-table:默认创建第三张表时,数据中标的名称
4.多对多关联关系的方式
方式一:自行创建第三张表
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name="书名")
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者姓名")
# 自己创建第三张表,分别通过外键关联书和作者
class Author2Book(models.Model):
author = models.ForeignKey(to="Author")
book = models.ForeignKey(to="Book")
class Meta:
unique_together = ("author", "book")
方式二:通过ManyToManyField自动创建第三张表
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name="书名")
# 通过ORM自带的ManyToManyField自动创建第三张表
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者姓名")
books = models.ManyToManyField(to="Book", related_name="authors")
方式三:设置ManyTomanyField并指定自行创建的第三张表
class Book(models.Model):
title = models.CharField(max_length=32, verbose_name="书名")
# 自己创建第三张表,并通过ManyToManyField指定关联
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="作者姓名")
books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))
# through_fields接受一个2元组('field1','field2'):
# 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。
class Author2Book(models.Model):
author = models.ForeignKey(to="Author")
book = models.ForeignKey(to="Book")
class Meta:
unique_together = ("author", "book")
注意:
当我们需要在第三张关系表中存储额外的字段时,就要使用第三种方式。
但是当我们使用第三种方式创建多对多关联关系时,就无法使用set、add、remove、clear方法来管理多对多的关系了,需要通过第三张表的model来管理多对多关系
三、断开外键关联的ForeignKey使用
# 1、不使用ForeignKey方式断开关联,不再支持Django ORM连表查询语法
class Publish(models.Model):
name = models.CharField(max_length=20)
class Book(models.Model):
name = models.CharField(max_length=20)
# 字段需要写_id来表示相关表的字段信息
publish_id = models.IntegerField()
# 2、使用ForeignKey方式用db_constraint=False字段属性断开关联,依然支持Django ORM连表查询语法,建议使用
class Publish(models.Model):
name = models.CharField(max_length=20)
class Book(models.Model):
name = models.CharField(max_length=20)
# 字段不需要写_id来表示相关表的字段信息,ORM会自动添加
publish = models.ForeignKey(to='Publish', null=True, on_delete=models.SET_NULL, db_constraint=False)
四、断开关联的多对多自动创建关系表
# 使用ManyToManyField方式用db_constraint=False字段属性断开关联,依然支持Django ORM连表查询语法,建议使用
class MyBook(models.Model):
name = models.CharField(max_length=20)
my_author = models.ManyToManyField(to='MyAuthor', db_constraint=False)
class MyAuthor(models.Model):
name = models.CharField(max_length=20)
五、断开关联的多对多手动创建关系表
# 手动创建关系表可以让关系表可以拥有更多的自身的字段,同时通过关系表类名可以直接获取第三张表
# 1、和自动建立关系表类似,依然支持Django ORM连表查询语法(多对多借助关系表连表查询)
class Book(models.Model):
name = models.CharField(max_length=20)
class Author(models.Model):
name = models.CharField(max_length=20)
class Book_Author(models.Model):
book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL, db_constraint=False)
author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL, db_constraint=False)
time = models.DateField()
# *****
#2、手动创建关系表,用ManyToManyField方式支持正向反向ORM连表查询,需要用db_constraint=False断开关联
-- to:多对多的关联类
-- through:手动建立的关系表
-- through_fields:('关系表中代表本类的字段名', '关系表中代表关联类的字段名')
class Book(models.Model):
name = models.CharField(max_length=20)
author = models.ManyToManyField(to='Author', through='Book_Author', through_fields=('book_id', 'author_id'), db_constraint=False)
class Author(models.Model):
name = models.CharField(max_length=20)
class Book_Author(models.Model):
book_id = models.IntegerField()
author_id = models.IntegerField()
time = models.DateField()
#3、手动创建关系表,在关系表中用ForeignKey方式支持基于外键关系表的ORM连表查询,同时明确ManyToManyField字段,所以也支持ORM正向方向连表查询
-- db_constraint=False断开关联可以在ForeignKey或ManyToManyField任意一方完成
class Book(models.Model):
name = models.CharField(max_length=20)
# 明确through与through_fields,ManyToManyField才不会自动建立关系表
author = models.ManyToManyField(to='Author', through='Book_Author', through_fields=('book_id', 'author_id'), db_constraint=False)
class Author(models.Model):
name = models.CharField(max_length=20)
class Book_Author(models.Model):
book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL, db_constraint=False)
author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL, db_constraint=False)
time = models.DateField()
# 总结:手动创建第三张表,第三张表的增删改就采用关系表类名衍生的create|delete|update,就不再拥有add|clear|remove|set(因为关系表拥有自己的字段,这些方法无法直接操作这些字段)