zoukankan      html  css  js  c++  java
  • python3开发进阶-Django框架中的ORM的常用操作的补充(F查询和Q查询,事务)

    阅读目录

    1. F查询和Q查询
    2. 事务

     

    一、F查询和Q查询

    1、F查询

    查询前的准备

    class Product(models.Model):
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=10, decimal_places=2)
    
        # 库存数
        inventory = models.IntegerField()
        # 卖出数
        sale = models.IntegerField()
    
    
        def __str__(self):
            return  "{}:{}:{}:{}".format(self.name, self.price, self.inventory, self.sale)
    app下的models
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (1, '跟大娃变大', 239, 1000, 10);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (2, '跟二娃学吹牛逼', 20150, 60, 60);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (3, '跟三娃学喊麦', 50150, 100, 0);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (4, '跟四娃学诗歌', 159, 50, 10000);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (5, '跟五娃学树新风', 155, 100, 200);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (6, '跟六娃学喷口水', 152, 200, 1);
    SQL数据名称:main_app01_product

    在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?

    Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

    示例1:

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

    from django.db.models import F
    models.Product.objects.filter(sale__gt=F('inventory'))

    Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

    models.Product.objects.filter(sale__lt=F('sale')*2)

    修改操作也可以使用F函数,比如将每一本书的价格提高30元

    models.Product.objects.update(price=F("price")+30)

    注意:update修改字段和对象,属性修改字段的区别:

      1、对象.属性方法会更新所有字段

      2、update方法只会更新你修改的那个字段

    引申:

    如果要修改char字段咋办?

    如:把所有书名后面加上(第一版)

    from django.db.models.functions import Concat
    from django.db.models import Value
    models.Product.objects.update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))

    2、Q查询

    1、多个查询条件做 交集 并集 取反操作时

    2、如果Q查询和关键字查询同时存在时,Q查询要放在关键字查询的前面

    filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象

    示例1:

    查询卖出数大于100或者价格小于100

    models.Product.objects.filter(Q(sale__gt=100)|Q(sale__lt=100))

    你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

    示例:查询库存数是100 并且 卖出数不是0 的商品

    models.Product.objects.filter(Q(inventory=100) & ~Q(sale=0))

    查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。

    例如:查询商品名包含喷口水,并且库存数大于60

    models.Product.objects.filter(Q(inventory__gt=60), name__icontains="喷口水")

    二、事务

    1、什么是事务?

      数据的原子性、隔离性、持久性、一致性

    class Product(models.Model):
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=10, decimal_places=2)
    
        # 库存数
        inventory = models.IntegerField()
        # 卖出数
        sale= models.IntegerField()
    
    
        def __str__(self):
            return  "{}:{}:{}:{}".format(self.name, self.price, self.inventory, self.sale)
    
    
    class Order(models.Model):
        num = models.CharField(max_length=64)
        product = models.ForeignKey(to="Product")
        count = models.IntegerField()
    models中的类
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (1, '跟大娃变大', 239, 1000, 10);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (2, '跟二娃学吹牛逼', 20150, 60, 60);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (3, '跟三娃学喊麦', 50150, 100, 0);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (4, '跟四娃学诗歌', 159, 50, 10000);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (5, '跟五娃学树新风', 155, 100, 200);
    INSERT INTO app01_product (id, name, price, inventory, sale) VALUES (6, '跟六娃学喷口水', 152, 200, 1);
    SQL数据main_app01_product
    import os
    
    if __name__ == '__main__':
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
        import django
        django.setup()
    
        import datetime
        from app01 import models
    
        try:
         from django.db.models import F  from django.db import transaction
    #买一本书
    #在数据库层面要做到的事儿
    #1、创建一条订单数据
    #2、去产品表 将卖出数+1,库存数-1 with transaction.atomic(): #开启事务处理
    #创建一条订单数据
           models.Order.objects.create(num='123456789',product_id=1,count=1)
    #去产品表 将卖出数+1,库存数-1(报错)
           models.Product.objects.get(id=1).update(inventory=F('inventory')-1,sale=F('sale')+1) 
    #能执行成功
    #models.Product.objects.filter(id=1).update(inventory=F('inventory'-1,sale=F('sale')+1))
    except Exception as e:
         print(e)  

    # 不开启事务
    # try:
    # # 创建一条订单数据
    # models.Order.objects.create(num="123456789", product_id=1, count=1)
    # # 去产品表 将卖出数+1, 库存数-1
    # models.Product.objects.get(id=1).update(kucun=F("kucun") - 1, maichu=F("maichu") + 1)
    # except Exception as e:
    # print(e)

     

  • 相关阅读:
    IISManager 的启动
    基于hadoop集群的hive 安装(mysql,derby)
    Struts中央控制器
    在Spring中配置Hibernate事务
    java 实现多线程下载
    hello,博客园
    easyui datagrid中添加右键菜单事件
    C#项目打包
    easyui datagrid中单击添加菜单事件
    SQL多条件查询拼接in中条件方法
  • 原文地址:https://www.cnblogs.com/ManyQian/p/9215349.html
Copyright © 2011-2022 走看看