辜老板 相信奇迹才会创造奇迹, 为了梦想. 狗屁梦想, 为了赚钱, 赚钱赚钱赚钱啊啊啊啊啊
博客园 首页 新随笔 联系 管理随笔 - 39 文章 - 0 评论 - 1
目录
一, 常用字段
- AutoField
- IntegerField
- CharField
4. 自定义及使用 char
- DateField
- DateTimeField
二, 字段合集
三, 字段参数
- null
- unique
- db_index
- default
四, DateField 和 DateTimeField
- auto_now_add
- auto_now
五, 关系字段
1.ForeignKey 一对多
字段参数
- to
- to_field
- on_delete
- db_constraint
5. 其余字段参数
2.OneToOneField 一对一
字段参数
- to
- to_field
- on_delete
3.ManyToManyField 多对多三种创建方式
1全自动 (常见)
2纯手动 (了解)
3半自动 (推荐)
六, choices 参数
1. 用户表举例
2. 基本运用
七, 数据库查询优化 (面试)
1. 惰性查询
2.only 与 defer 的用法
noly 的使用:
defer 的使用:
大白话总结:
3.selected_related 与 prefetch_related
八, Djangi ORM 中如何开启事物
九, MTV 与 MVC 模型
一, 常用字段
1.AutoField
int 自增列, 必须填入参数 primary_key=True. 当 model 中如果没有自增列, 则自动会创建一个列名为 id 的列.
2.IntegerField
一个整数类型, 范围在 -2147483648 to 2147483647.(一般不用它来存手机号 (位数也不够), 直接用字符串存,)
3.CharField
字符类型, 必须提供 max_length 参数, max_length 表示字符长度.
这里需要知道的是 Django 中的 CharField 对应的 MySQL 数据库中的 varchar 类型, 没有设置对应 char 类型的字段, 但是 Django 允许我们自定义新的字段, 下面我来自定义对应于数据库的 char 类型
自定义字段在实际项目应用中可能会经常用到, 这里需要对他留个印象!
4. 自定义及使用 char
- from django.db import models
- # Create your models here.
- #Django 中没有对应的 char 类型字段, 但是我们可以自己创建
- class FixCharField(models.Field):
- '''
- 自定义的 char 类型的字段类
- '''
- def __init__(self,max_length,*args,**kwargs):
- self.max_length=max_length
- super().__init__(max_length=max_length,*args,**kwargs)
- def db_type(self, connection):
- '''
- 限定生成的数据库表字段类型 char, 长度为 max_length 指定的值
- :param connection:
- :return:
- ''' return'char(%s)'%self.max_length
- # 应用上面自定义的 char 类型
- class Class(models.Model):
- id=models.AutoField(primary_key=True)
- title=models.CharField(max_length=32)
- class_name=FixCharField(max_length=16)
- gender_choice=((1,'男'),(2,'女'),(3,'保密'))
- gender=models.SmallIntegerField(choices=gender_choice,default=3)
- 5.DateField
日期字段, 日期格式 YYYY-MM-DD, 相当于 Python 中的 datetime.date() 实例.
6.DateTimeField
日期时间字段, 格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ], 相当于 Python 中的 datetime.datetime() 实例.
二, 字段合集
AutoField(Field)
- int 自增列, 必须填入参数 primary_key=True
BigAutoField(AutoField)
- bigint 自增列, 必须填入参数 primary_key=True
注: 当 model 中如果没有自增列, 则自动会创建一个列名为 id 的列
- from django.db import models
- class UserInfo(models.Model):
- # 自动创建一个列名为 id 的且为自增的整数列
- username = models.CharField(max_length=32)
- class Group(models.Model):
- # 自定义自增列
- nid = models.AutoField(primary_key=True)
- name = models.CharField(max_length=32)
- SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列 (有符号的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField):
- 长整型 (有符号的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field):
- 可以为空的布尔值
CharField(Field)
- 字符类型
- 必须提供 max_length 参数, max_length 表示字符长度
TextField(Field)
- 文本类型
EmailField(CharField):
- 字符串类型, Django Admin 以及 ModelForm 中提供验证机制
IPAddressField(Field)
- 字符串类型, Django Admin 以及 ModelForm 中提供验证 IPV4 机制
GenericIPAddressField(Field)
- 字符串类型, Django Admin 以及 ModelForm 中提供验证 Ipv4 和 Ipv6
- 参数:
protocol, 用于指定 Ipv4 或 Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为 True, 则输入::ffff:192.0.2.1 时候, 可解析为 192.0.2.1, 开启此功能, 需要 protocol="both"
URLField(CharField)
- 字符串类型, Django Admin 以及 ModelForm 中提供验证 URL
SlugField(CharField)
- 字符串类型, Django Admin 以及 ModelForm 中提供验证支持 字母, 数字, 下划线, 连接符 (减号)
CommaSeparatedIntegerField(CharField)
- 字符串类型, 格式必须为逗号分割的数字
UUIDField(Field)
- 字符串类型, Django Admin 以及 ModelForm 中提供对 UUID 格式的验证
FilePathField(Field)
- 字符串, Django Admin 以及 ModelForm 中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
FileField(Field)
- 字符串, 路径保存在数据库, 文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件, 默认 django.core.files.storage.FileSystemStorage
ImageField(FileField)
- 字符串, 路径保存在数据库, 文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件, 默认 django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名 (字符串)
height_field=None 上传图片的宽度保存的数据库字段名 (字符串)
DateTimeField(DateField)
- 日期 + 时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]]
DurationField(Field)
- 长整数, 时间间隔, 数据库中按照 bigint 存储, ORM 中获取的值为 datetime.timedelta 类型
FloatField(Field)
- 浮点型
DecimalField(Field)
- 10 进制小数
- 参数:
max_digits, 小数总长度
decimal_places, 小数位长度
BinaryField(Field)
- 二进制类型
对应关系:
- '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.null
用于表示某个字段可以为空.
2.unique
如果设置为 unique=True 则该字段在此表中必须是唯一的 .
3.db_index
如果 db_index=True 则代表着为此字段设置索引.
4.default
为该字段设置默认值.
四, DateField 和 DateTimeField
1.auto_now_add
配置 auto_now_add=True, 创建数据记录的时候会把当前时间添加到数据库.
- publish_time = models.DateField(auto_now_add=True)
- publish_time = models.DateTimeField(auto_now_add=True)
- 2.auto_now
配置上 auto_now=True, 每次更新数据记录的时候会更新该字段.
- publish_time = models.DateField(auto_now=True)
- publish_time = models.DateTimeField(auto_now=True)
五, 关系字段
1.ForeignKey 一对多
外键类型在 ORM 中用来表示外键关联关系, 一般把 ForeignKey 字段设置在 '一对多'中'多'的一方.
ForeignKey 可以和其他表做关联关系同时也可以和自身做关联关系.
- # 图书表
- class Book(models.Model):
- title = models.CharField(max_length=32)
- price = models.DecimalField(max_digits=8, decimal_places=2)
- publish_time = models.DateField(auto_now_add=True)
- # 出版社外键
- # 一本书有一个出版社, 一个出版社可以出版多本书. 一对多的关系
- publish = models.ForeignKey(to='Publish') # 一对多
- # 一本书 可以又多个作者, 一个作者可以写多本书. 多对多
- authors = models.ManyToManyField(to='Author')
字段参数
1.to
设置要关联的表
2.to_field
设置要关联的表的字段
3.on_delete
当删除关联表中的数据时, 当前表与其关联的行的行为.
models.CASCADE
删除关联数据, 与之关联也删除
4.db_constraint
是否在数据库中创建外键约束, 默认为 True.
5. 其余字段参数
models.DO_NOTHING
删除关联数据, 引发错误 IntegrityError
models.PROTECT
删除关联数据, 引发错误 ProtectedError
models.SET_NULL
删除关联数据, 与之关联的值设置为 null(前提 FK 字段需要设置为可空)
models.SET_DEFAULT
删除关联数据, 与之关联的值设置为默认值 (前提 FK 字段需要设置默认值)
models.SET
删除关联数据,
a. 与之关联的值设置为指定值, 设置: models.SET(值)
b. 与之关联的值设置为可执行对象的返回值, 设置: models.SET(可执行对象)
- def func():
- return 10
- class MyModel(models.Model):
- user = models.ForeignKey(
- to="User",
- to_field="id",
- on_delete=models.SET(func)
- )
2.OneToOneField 一对一
通常一对一字段用来扩展已有字段.(通俗的说就是一个人的所有信息不是放在一张表里面的, 简单的信息一张表, 隐私的信息另一张表, 之间通过一对一外键关联)
- # 作者表
- class Author(models.Model):
- name = models.CharField(max_length=32)
- age = models.IntegerField()
- # 一个作者有一个作者详情, 一个详情只有一个作者. 一对一
- author_detail = models.OneToOneField('AuthorDetail')
字段参数
1.to
设置要关联的表.
2.to_field
设置要关联的字段.
3.on_delete
当删除关联表中的数据时, 当前表与其关联的行的行为.
3.ManyToManyField 多对多三种创建方式
1全自动 (常见)
好处: 第三张表自动创建, 并且会自动帮你在字段名后加'_id'后缀
不足之处: 第三张表无法扩展额外的字段, 扩展性低
- # 图书表
- class Book(models.Model):
- title = models.CharField(max_length=32)
- price = models.DecimalField(max_digits=8, decimal_places=2)
- publish_time = models.DateField(auto_now_add=True)
- # 出版社外键
- # 一本书有一个出版社, 一个出版社可以出版多本书. 一对多的关系
- publish = models.ForeignKey(to='Publish') # 一对多
- # 一本书 可以又多个作者, 一个作者可以写多本书. 多对多
- authors = models.ManyToManyField(to='Author') # Author 是多对多的另一张表名
2纯手动 (了解)
好处: 第三表可以扩展额外的字段
不足之处: ORM 查询的时候会带来不便
- class Book(models.Model):
- title = models.CharField(max_length=32)
- class Author(models.Model):
- name = models.CharField(max_length=32)
- class Book2Author(models.Model):
- book = models.ForeignKey(to='Book')
- author = models.ForeignKey(to='Author')
- create_time = models.DateField(auto_now_add=True)
3半自动 (推荐)
好处: 第三张表可以扩展任意的额外字段 还可以利用 ORM 正反向查询
不足之处: 无法利用 add set remove clear 对外键关系表操作
但是: 虽然无法使用了 但我们还可以自己直接操作第三表, 扩展性极高
- class Book(models.Model):
- title = models.CharField(max_length=32)
- authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
- class Author(models.Model):
- name = models.CharField(max_length=32)
- books = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('author','book'))
- class Book2Author(models.Model):
- book = models.ForeignKey(to='Book')
- author = models.ForeignKey(to='Author')
- create_time = models.DateField(auto_now_add=True) # 自动添加创建时间
六, choices 参数
条件可以被完全列举出来 有对应关系
该字段存的还是数字并且没有范围限制, 但是一旦你存的数字在你上面定义的对应关系内
那么你就可以通过下面的方法获取到数字对应的解释信息
get_xxx_display() 如果没有对应关系返回的还是数字
获取值: user_obj.get_gender_display()
- # 只要有对应关系即可 前面不一定非要是数字
- # 如果数字没有对应的关系, 那么还是获取到数字本身
1. 用户表举例
用户的性别
学历
婚否
在职状态
客户来源
当你的数据能够被你列举完全 你就可以考虑使用 choices 参数
2. 基本运用
案例 1:
- # choices 字段
- class Userinfo(models.Model):
- username = models.CharField(max_length=32)
- gender_choices = (
- (1,'男'),
- (2,'女'),
- (3,'其他'),
- )
- gender = models.IntegerField(choices=gender_choices)
- # 该字段还是存数字 并且可以匹配关系之外的数字
案例 2:
- record_choices = (('checked', "已签到"),
- ('vacate', "请假"),
- ('late', "迟到"),
- ('noshow', "缺勤"),
- ('leave_early', "早退"),
- )
- record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
获取值:
- user_obj = models.Userinfo.objects.get(pk=1)
- print(user_obj.username)
- print(user_obj.gender)
- # 针对 choices 参数字段 取值的时候 get_xxx_display()
- print(user_obj.get_gender_display())
- # # 针对没有注释信息的数据 get_xxx_display() 获取到的还是数字本身
- user_obj = models.Userinfo.objects.get(pk=4)
- print(user_obj.gender)
- print(user_obj.get_gender_display())
七, 数据库查询优化 (面试)
1. 惰性查询
惰性: 不会白白的帮你多干事情, 减缓数据库的压力
惰性查询: 如果下面的代码没有使用 res, 那么就不会帮你查询. 只有使用了才会帮你查询.
django ORM 查询都是惰性查询
- res = models.Book.objects.all() # django ORM 查询都是惰性查询
- printf(res) # 使用了 res
2.only 与 defer 的用法
noly 的使用:
- res = models.Book.objects.only('title') # 這些对象内部只有 title 屬性
- # print(res)
- for r in res:
- print(r.title) # only 括号内有 title 属性, 不走数据库
- print(r.price) # 括号内没有 price 属性, 走数据库拿
defer 的使用:
- res = models.Book.objects.defer('title') # defer 与 only 互为反关系
- print(res)
大白话总结:
大白话总结:
defer 与 only 互为相反, 获取没有的数据走数据库拿.
only: 括号内有指定的字段属性
defer: 括号内没有指定的字段属性
3.selected_related 与 prefetch_related
selected_related: 内部是连表操作, 封装到对象, 走一次数据库全部查出
优点: 只走一次 sql 查询
缺点: 耗时耗在 连接表的操作 10s
prefetch_related: 内部是子查询
优点: 耗时耗在 查询次数比如 10 次 1s
缺点: 走两次 sql 查询
使用方法:
- res = models.Book.objects.select_related('publish')
- print(res)
- res = models.Book.objects.prefetch_related('publish')
- print(res)
八, Djangi ORM 中如何开启事物
原子性:
原子性 (Atomicity), 原子意为最小的粒子, 即不能再分的事务, 要么全部执行, 要么全部取消 (就像上面的银行例子)
一致性:
一致性 (Consistency): 指事务发生前和发生后, 数据的总额依然匹配
隔离性:
隔离性 (Isolation): 简单点说, 某个事务的操作对其他事务不可见的
持久性:
持久性 (Durability): 当事务完成后, 其影响应该保留下来, 不能撤消, 只能通过 "补偿性事务" 来抵消之前的错误
开启事务:
start transaction 开启
rollback 回滚
commit 确认
- from django.db import transaction
- # django ORM 开启事务操作
- from django.db import transaction
- with transaction.atomic():
- # 在 with 代码块中执行的 ORM 语句同属于一个事务
- pass
九, MTV 与 MVC 模型
MTV: django 号称是 MTV 框架
M 指: models 模型
T :templates 模版
V :views 视图
MVC
M:models 模型
V:views 视图
C:contronnar 控制器 (路由分发 urls.py)
本质
本质: MTV 本质也是 MVC
BMS
web 领域没有绝对的安全 也没有绝对的不安全
来源: https://www.cnblogs.com/guyouyin123/p/12177755.html