ORM常用字段及参数,事务及其他
1、models常用字段及参数
字段后设置属性verbose_name=' ' 可以将该字段在admin后台以中文名展示
1、常用字段
1、主键字段:AutoField(primary_key = True) 可以不写Django会自动添加一个名为id的主键字段,必须填primary_key = True
2、varchar(32):CharField(max_length = 32,verbose_name='名字') Django只有varchar字符类型字段,且必须要写max_length
3、int:IntegerField() 整型可以不传数字,默认是11位
4、bigint:BigIntegerField() 长整型,存更多的数字
5、decimal:DecimalField(max_digits=8, decimal_places=2) 存小数数字总共max_digits,小数位decimal_places
6、date:DateField() 存年月日日期,可以设置格式化时间,可以传auto_now和auto_now_add
auto_now:每次编辑数据的时候都会自动更新该字段时间
auto_now_add:只在创建的时候自动更新
7、datetime:DateTimeField() 存年月日时分秒,可以设置格式化时间,可以传auto_now 和 auto_now_add
auto_now:每次编辑数据的时候都会自动更新该字段时间
auto_now_add:只在创建的时候自动更新
8、varchar(254):EmailField()
9、bool:BooleanField() 给该字段传布尔值会对应生成数字 0/1
10、文本类型:TextField 可以存储大段文本
11、FileField(upload_to=" ") 字符串路径保存到数据库,文件上传到指定的目录,给该字段传文件对象,文件会自动保存到upload_to指定的文件夹下
12、ImageField(upload_to="文件夹", default="设置文件夹下的默认图片")
2、自定义类型字段
我们以自定义一个char类型字段为例
1、默认字段都继承了Field类,我们先导入Field
from django.db.models import Field
2、自定义char类型字段继承Field
class MyCharField(Field): def __init__(self, max_length, *args, **kwargs): self.max_length = max_length # 拦截父类的方法,操作完后利用super调用父类的方法 super().__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection): return "char(%s)"%self.max_length
3、自定义后使用
class Movie(models.Model): title = MyCharField(max_length=64)
3、字段类的关键性参数
null:一般在一张表中已经有字段了,再新添加一个字段时使用设置为null=True,也可以新建字段时设置可以为空
default:一般在一张表中已经有字段了,再新添加一个字段时使用设置之前的数据该字段默认值,也可以初始设置一个默认值数据
Django 1.x版本使用的是级联更新级联删除,2.x版本需要手动指定
2、choices参数
当数据能够被列举完,可以供用户选择的时候,可以考虑用choices参数,比如性别,学历,婚否等等
# choices字段 class Userinfo(models.Model): username = models.CharField(max_length=32) gender_choices = ( (1,'男'), (2,'女'), (3,'其他'), ) gender = models.IntegerField(choices=gender_choices) # 该字段还是存数字 并且可以匹配关系之外的数字 # 该字段还可以存字符串 record_choices = ( ('vacate', "请假"), ('late', "迟到"), ('noshow', "缺勤"), ('leave_early', "早退"), ) record = models.CharField('上课记录', choices=record_choices, default='checked', max_length=32)
2、使用choices,取值的时候使用对象.get_xxx_display()来获取choices后面具体的值,当choices中没有该数据对应的时候获取的还是数字本身
user_obj = models.Userinfo.objects.get(pk=1) # 针对choices参数字段 取值的时候 get_xxx_display() print(user_obj.get_gender_display()) # 男 # 针对没有注释信息的数据 get_xxx_display()获取到的还是数字本身 user_obj = models.Userinfo.objects.get(pk=4) print(user_obj.get_gender_display()) # 4
3、ORM查询优化
查询时想看见SQL原生语句可以在配置文件中配置一下
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
Django的ORM查询都是惰性查询,即不使用该查询得到的对象时,即使写了该条查询语句也不会去数据库中查询,只有当后面使用到了才会去数据库中查询
1、only与defer
only的作用:括号内传字段,得到的结果是一个列表套数据对象,该对象内只含有括号内指定的字段属性,对象点该字段属性是不会走数据库的,但是一旦点了非括号内的字段也可以拿到数据,但是要重新走数据库
res = models.Publish.objects.only('name') for i in res: # print(i.name) # 括号中数据是only内的属性只会查询一次 print(i.addr) # 括号中数据不是only查询的每一个都会重新去数据库中查找
defer的作用:与only相反,得到的结果是列表套数据对象,通过对象点括号内的字段会重复走数据库查询,当对象点非括号内的字段就不会走数据库
res = models.Book.objects.defer('name') for i in res: # print(i.name) # 括号中数据是only内的属性每次查询会重复查询数据库 print(i.price) # 括号中字段不是defer内字段,查询只会查询一次
2、select_related与prefetch_related
select_related: 内部时连表操作,将关系表全部链接起来,之后再一次性查询封装到对象中,再通过对象点属性就不需要走数据库了,select_related括号内只能是外键字段,并且不能是多对多,只能能是一对一或一对多
res = models.Book.objects.select_related('publish') for i in res: # print(i.publish.name) print(i.publish.addr)
prefetch_related:内部时子查询,但是感觉像是连表操作,其实内部时子查询将全部的封装到对象中之后对象点当前表或者关联表中字段就不需要走数据库了
res = models.Book.objects.prefetch_related('publish') for i in res: # print(i.publish.name) print(i.publish.addr)
select_related与prefetch_related优缺点比较:
select_related连表操作 只走一个SQL查询,耗时耗在连表操作
prefetch_related子查询 走两次SQL查询耗时耗在查询次数
4、Django的ORM中的事务操作
事务的四大特性ACID:原子性、一致性、隔离性、持久性(在数据库中讲过此处就不细讲了)
1、Django ORM开启事务:
from django.db import transaction
2、使用事务
with transaction.atomic(): # 在with代码块中执行ORM语句属于同一个事务,代码块运行结束事务就结束了
5、MTV与MVC模型
MTV:Django号称MTV框架,其实本质上也是MVC
M:models 模型层
T:templates 模板层
V:views 视图层
MVC:
M:models 模型层
V:views 视图层
C: controller 控制器(路由分发 urls.py)