zoukankan      html  css  js  c++  java
  • 特殊查询常用字段,事务操作

    知识提纲

    聚合查询
    关键字:aggregate
    from django.db.models import Max,Min,Count,Sum,Avg

    分组查询
        关键字:annotate
        1.最简单的规律
            models后面点什么 就是按什么分组  
        
    F与Q查询
        from django.db.modles import F,Q
        F  能够帮助你获取到表中字段所对应的数据
        # 书籍的库存数与卖出数
        models.Book.objects.filter(kucun__gt=F('maichu'))
        
        因为filter过滤的条件的都是and连接 
        modesls.Book.objects.filter(Q(title='python'),Q(price=666))
        modesls.Book.objects.filter(Q(title='python')|Q(price=666))
        modesls.Book.objects.filter(~Q(title='python')|Q(price=666))
        
        # Q进阶用法
        q = Q()
        q.connector = 'or'
        q.children.append(('title','python'))
        q.children.append(('title__icontains','python'))
        q.children.append(('price',666))
        models.Book.objects.filter(q)  # 默认还是and关系  
    
    django中如何开启事务
        from django.db import transaction
        try:
            with transaction.atomic():
                # 事务操作
        except BaseException as e:
            print(e)  
    

    常见字段及参数
        AutoField()
        DateField()
        DateTimeField()
            auto_now
            auto_now_add
        TextField()
        EmailField()          varchar(...)
        BooleanField()        传布尔值  存0/1
    


    自定义char字段
        class MyCharField(models.Field):
    

            def db_type(self,connection):
                return 'char(%s)'%self.max_length
    

    orm查询优化

        only
        defer
    

    聚合查询

    1. aggregate()是QuerySet的一个终止子句,意思是说,它返回字典.
    2. 键的名称是聚合值得标识符,值是根据聚合函数计算的值,
    3. 键的名称可以自动生出来,也可以向聚合子句提供它.
    from django.db.models import Avg,Sum,Max,Min,Count
    # 键名称自动的结果为price__avg对应着结果
    models.Book.objects.all().aggregate(Avg('price'))
    
    # 向聚合子句提供它
    models.Book.objects.all().aggregate(avg_price=Avg('price'))
    
    

    分组查询

    annotate分组依据是前面的值.

    示例统计出每个出版社买的最便宜的书的价格.

    publisher_list = models.Publisher.objects.annotate(min_price=Min("book__price"))
    for obj in publisher_list:
        print(obj.min_price)
    
        
    

    示例2.统计出每一本书的作者个数

    book_list = models.Book.objects.all().annotate(author_num=Count("author"))
    for obj in book_list:
        print(obj.author_num)
    
    
    # 3.统计不止一个作者的图书
    """
    1.统计每本书对应的作者个数
    2.基于上面的结果 筛选出作者个数大于1 的
    
    """
    res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num')
    print(res)
    

    F查询

    我们构造的过滤器都只是将字段值和我们设定的某个常量相比较,但是如果想要比较两个字段的值怎么做呢?

    不必担心,.Django 就提供了F()来解决这种问题,

    F()的实例可以在查询中引用字段,比较同一个model实例中的两个不同的字段的值.

    例如查询卖出数大于库存数的商品

    from django.db models import F
    rest=models.talble_name.objects.filter(maichu__gt=F('kuncun'))
    print(rest)
    

    总结:F可以取到表中的字段的对应值当做筛选的一个条件,而不是自定义敞亮的条件了,实现了动态的比较的效果

    进阶:Django还支持F()对象之间以及F()对象和常数之间的加减乘除和取模的操作,根据表中的数据类型进行数学运算

    例如将每个商品的价格都提高50块

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

    char字段修改:

    利用Concat操作,进行拼接字符串,而且还得加上拼接的值value,位置的参数决定了头部尾部拼接,

    from django.db.models.functions import Concat
    from django.db.models import Value
    ret3=models.Product.objects.update(name=Concat(F('name'),Value('新款')))
    

    Q查询

    filter()等方法中逗号隔开的条件是and的关系,如果要变成or的关系就可以使用Q对象,出现Q对象就必须位于关键字参数前面

    例如查询卖出数量大于100,价格却小于100元的:

    from django.db.models import Q
    models.Product.objects.filter(Q(maichu__gt=100)|Q(price__lt=100))
    

    使用方法:用Q包裹条件,|隔开

    进阶:&和|操作符以及~操作符
    Q对象使用~操作符 就是not的查询

    Q查询可以产生对象然后再使用

    # q = Q()
    # q.connector = 'or'
    # q.children.append(('title__icontains','p'))
    # # q.children.append(('kucun',666))
    # res = models.Book.objects.filter(q)
    # print(res)
    

    orm中常见字段

        AutoField(primary_key=True)
        CharField(max_length=32)   varchar(32)
        IntegerField()             int
        BigIntegerField()          long
        DateField()
            auto_now:每次修改数据的时候 都会更新该字段
            auto_now_add:只在创建数据的时候 才会自动将创建时间添加 后续不会再自动修改了
        DecimalField()
        BooleanField(Field)
            - 布尔值类型
            该字段在存储数据的时候 你只需要传布尔值即可
            对应到数据库中 会变成0/1
        TextField(Field)
            - 文本类型
            存大段文本
        EmailField(CharField)               varchar(...)
        FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
        DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度
    

    自定义char字段

        # 自定义char类型字段
        class MyCharField(models.Field):
            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):
                return 'char(%s)'%self.max_length
    

    Django2.0注意事项

    如果你使用的是django2.X版本 你在建数据库表关系的时候
    你需要手动指定两个参数
        (你要手动告诉django  级联更新 级联删除  是否建外键约束)
        
        on_delete
        db_constraint
    

    django orm中的事务操作

    将sql语句操作变成原子性的操作,要么同时成功,只要有一个失败,就回滚原来的状态,保证数据的完整一致性(NoSQL数据对于事务是部分支持的)

        ACID
            原子性
            一致性
            隔离性
            持久性
            commit
            rollback
    

        from django.db import transaction
        with transaction.atomic():
            # 在该代码块中所写的orm语句 同属于一个事务
        # 缩进出来之后自动结束
    

  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/jhpy/p/11753049.html
Copyright © 2011-2022 走看看