• 模型层(下)


    django模板层下

    一、聚合查询与分组查询

    1.1 聚合

    ​ 聚合函数是sql的基本函数,会对一组值执行计算并返回单一的值。

    from django.db.models import Avg,Sun,Max,Min,Count
    
    res1 = models.Book.objects.all().aggregate(Avg('price'))
    res2 = models.Book.objects.all().aggregate(Max('price'))
    res3 = models.Book.objects.all().aggregate(Min('price'))
    res4 = models.Book.objects.all().aggregate(Sum('price'))
    res5 = models.Book.objects.all().aggregate(Count('title'))
    res6 = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'),Sum('price'),Count('title'))
    

    1.2 分组

    ​ 分组查询使用关键字annotate()方法。

    ​ 1.统计每一本书的作者个数:

    res = models.Book.objects.annotate(author_num = Count('author')).values('author_num')
    

    ​ 2.统计每个出版社卖的价格做便宜的书的价格:

    res = models.Publish.objects.annotate(price_min=min(;book__price)).values('price_min')
    

    ​ 3.统计不止一个作者的图书:

    res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num')
    

    ​ 4.查询每个作者出的图书的总价:

    res = models.Author.object.annotate(sun_price=Sum('book__price')).values('sum_price')
    

    二、F与Q查询:

    2.1 F查询

    ​ jango提供的F()方法可以在查询中引用字段,比较来自同一个model中的两个不同字段的值。

    from django.db.models import F
    

    ​ 1.查询出卖出数大于库存数的商品:

    res = models.Product.objects.filter(maichu__gt=F('kucun'))
    

    ​ F可以取到表中某个字段对应的值来当作筛选条件,而不是自定义常量的条件了,实现了动态比较的效果。

    ​ Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。基于此可以对表中的数值类型进行数学运算。

    ​ 将每个商品的价格提高50块:

    res = models.Product.object.update(price=F('price')+50)
    

    2.2 Q查询

    filter() 等方法中逗号隔开的条件是与的关系。 如果需要执行更复杂的查询(例如OR语句),可以使用Q对象

    from django.db.models import Q
    
    

    ​ 1.查询 卖出数大于100 或者 价格小于100块的:

    res = models.Prodect.object.filter(Q(maichu__gt=100)|Q(price__lt=100))
    
    

    ​ 2.查询 库存数是100 并且 卖出数不是0 的产品:

    res = models.Prodect.objects.filter(Q(kucun=100)&~Q(maichu=0))
    
    

    三、orm中的字段

    3.1 常见字段

    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)
            - 二进制类型
    
     字段合集
    
    

    3.2 字段参数

    null
    	-用于表示某个字段可以为空。
    unique
    	-如果设置为unique=True 则该字段在此表中必须是唯一的 。
    
    db_index
    	-如果db_index=True 则代表着为此字段设置索引。
    
    default
    	-为该字段设置默认值。
        
    auto_now_add
    	-配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
    
    auto_now
    	-配置上auto_now=True,每次更新数据记录的时候会更新该字段。
        
    to
    设置要关联的表
    
    to_field
    设置要关联的表的字段
    
    on_delete
    当删除关联表中的数据时,当前表与其关联的行的行为。
    
    models.CASCADE
    
    删除关联数据,与之关联也删除
    
    db_constraint
    是否在数据库中创建外键约束,默认为True。
    
    

    四、查询与优化

    4.1 only与defer

    ​ only:

    res = models.Book.object.all()
    for i in res:
        print(r.title)
    
    

    ​ only会将括号内的字段对应的值,直接封装到返回给你的对象中点该字段,不需要再走数据库一旦你点了不是括号内的字段 ,就会频繁的去走数据库查询。

    ​ defer:

    res = models.Book.objects.defer('title')  # defer和only互为反关系
    for r in res:
        print(r.title)
    
    

    ​ defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中 点该其他字段,不需要再走数据库一旦你点了括号内的字段,就会频繁的去走数据库查询。

    ​ select_related 会自动做连表操作,然后将连表之后的数据全部查询出来封装给对象select_related括号内只能放外键字段,并且多对多字段不能放。如果括号内外键字段所关联的表中还有外键字段,还可以继续连表。select_related(外键字段__外键字段__外键字段...)

    res = models.Book.objects.select_related('publish')
    
    

    ​ prefetch_related看似连表操作,其实是类似于子查询prefetch_related括号内只能放外键字段 。并且多对多字段不能放 ,如果括号内外键字段所关联的表中还有外键字段,还可以继续连表 ,select_related(外键字段__外键字段__外键字段...)。

    res = models.Book.objects.prefetch_related('publish')
    print(res)
        for r in res:
            print(r.publish.name)
    
    

    五、事务

    ​ 事务的定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)。

    ​ 事务的四大特点:

    1. 原子性;
    2. 持久性;
    3. 一致性;
    4. 隔离性。

    ​ django中开启事务:

    from django.db import transation
    with transaction.atomic():
        # 在该代码块中所写的orm语句 同属于一个事务
    
    # 缩进出来之后自动结束
    
    
  • 相关阅读:
    解决 JDK1.7 不支持 VCenter 6.7 的问题(涉及到Https TLS1.2协议)
    无法删除另一个分区的windows文件夹
    首次将项目从eclipse提交到服务器的SVN
    无法截图右键菜单
    配置文件无法修改(以修改my-default.ini为例)
    运行JavaWeb项目报错Access denied for user 'root'@'localhost' (using password: YES)
    jquery.page.js插件在使用时重复触发“上一页”和“下一页”操作
    请求ajax失败的原因(进入到error)
    ajax请求执行完成后再执行其他操作(jQuery.page.js插件使用为例)
    img标签src资源无法加载,报net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION错
  • 原文地址:https://www.cnblogs.com/tangceng/p/11748234.html
Copyright © 2020-2023  润新知