zoukankan      html  css  js  c++  java
  • Django查询优化、ORM字段相关

    Django查询优化、ORM字段相关

    一、models常用字段及参数

    1. AutoField(primary_key=True)  主键字段
    2. CharField(max_length=32)     varchar(32)
    3. IntegerField()               int
    4. BigIntergerField()           bigint
    5. DecimalField()               decimal
    6. EmailField()                 varchart(254)
    7. DateField()					 date
    8. DateTimeField()              datetime
       		auto_now:每次编辑数据的时候都会自动更新该字段时间
        	auto_now_add:创建数据的时候自动更新
    9. BooleanField(Field)
            给该字段传布尔值 会对应成  数字0/1
            is_delete
            is_status
            is_vip
    10. TextField(Field)
            - 文本类型
            存储大段文本
      11. FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录,只存文件路径
            upload_to = '指定文件路径'
            给该字段传文件对象 文件会自动保存到upload_to指定的文件夹下 然后该字段存文件的路径
    

    自定义char类型字段

    自定义一个类,重写——init——方法,再利用super调用父类的方法,完成自定义字段类。

    from django.db.models import Field
    
    
    class RealCharField(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
    
    class Movie(models.Model):
           textField = RealCharField(max_length=64)
    

    字段内的关键性参数

    null
    default
    
    django 1.x默认就是级联更新级联删除  django2.x需要你自己手动指定
    on_delete = models.CASCADE
    db_contraints = True
    # 百度
    

    二、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 = (('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())
    

    三、orm查询优化相关

    res = models.Book.objects.all()  # django orm查询都是惰性查询
    print(res)
    
    
    res = models.Book.objects.values('title')
    print(res)
    for r in res:
        print(r.title)
    
        res = models.Book.objects.only('title')  # 這些對象内部只有title屬性
        # print(res)
        for r in res:
            # print(r.title)
            print(r.price)
            
            """
        only作用
            括号内传字段 得到的结果是一个列表套数据对象 该对象内只含有括号内指定的字段属性
            对象点该字段属性是不会走数据库的 但是你一旦点了非括号内的字段 也能够拿到数据
            但是是重新走的数据库查询吧
        """
    
            # res = models.Book.objects.defer('title')  # defer与only互为反关系
            # for r in res:
            #     print(r.title)
            """
        defer与only相反
            括号内传字段 得到的结果是一个列表套数据对象 该对象内没有括号内指定的字段属性
            对象点该字段属性会重复走数据库 但是你一旦点了非括号内的字段 就不走数据库了
        """
    
    
            # select_related和prefetch_related
            # res = models.Book.objects.get(pk=1)
            # print(res.publish.name)
    
            # res = models.Book.objects.select_related('authors')
            # for r in res:
            #     print(r.publish.name)
            #     print(r.publish.addr)
            """
        内部是连表操作 现将关系表全部链接起来 之后再一次性查询出来 封装到对象中
        数据对象之后在获取任意表中的数据的时候都不需要再走数据库了 因为全部封装成了对象的属性
    
        select_related括号内只能传外键字段 并且不能是多对多字段 只能是一对多和一对一
        select_related(外键字段1__外键字段2__外键字段3...)
        """
    
            # prefetch_related
            # res = models.Book.objects.prefetch_related('publish')
            # # print(res)
            #
            # for r in res:
            #     print(r.publish.name)
    
            """
        prefetch_related内部是子查询 但是给你的感觉是连表操作
        内部通过子查询将外键管理表中的数据页全部给你封装到对象中
        之后对象点当前表或者外键关联表中的字段也都不需要走数据库了
        """
            """
        优缺点比较
        select_related连表操作 好处在于只走一次sql查询
            耗时耗在 连接表的操作  10s
    
        prefetch_related子查询  走两次sql查询
            耗时耗在 查询次数      1s
        """
    

    四、orm中的事务操作

    # django orm开启事务操作
    from django.db import transaction
    with transaction.atomic():
        # 在with代码块中执行的orm语句同属于一个事务
        pass
    
    # 代码块运行结束 事务就结束了  事务相关的其他配置 你可以百度搜搜看
    
    	django orm如何开启事务操作
    		事务的四大特性(ACID)
    			原子性
    			一致性
    			隔离性
    			持久性
    				start transaction
    				rollback
    				commit
    		日考题
    			数据库的三大设计范式
    			自己百度搜索 用自己的话总结出三大范式的特点
    
    		# django orm开启事务操作
    		from django.db import transaction
    		with transaction.atomic():
    			# 在with代码块中执行的orm语句同属于一个事务
    			pass
    
    		# 代码块运行结束 事务就结束了  事务相关的其他配置 你可以百度搜搜看
    
    

    五、MTV与MVC模型

    	MTV与MVC模型
    		MTV  django号称是MTV框架
    			M:models
    			T:templates
    			V:views
    		MVC
    			M:models
    			V:views
    			C:contronnar  控制器(路由分发 urls.py)
    		本质:MTV本质也是MVC
    
    我把月亮戳到天上 天就是我的 我把脚踩入地里 地就是我的 我亲吻你 你就是我的
  • 相关阅读:
    2010浙大:zoj问题
    Meta 数据中文显示
    django 中间件
    url的配置
    django.contirb
    os模块
    线程和异步
    ADO.NET
    C#托管代码 CLR
    C#垃圾回收
  • 原文地址:https://www.cnblogs.com/zhulipeng-1998/p/12863877.html
Copyright © 2011-2022 走看看