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)

原文地址:https://www.cnblogs.com/ManyQian/p/9215349.html

时间: 2024-10-24 08:23:13

python3开发进阶-Django框架中的ORM的常用操作的补充(F查询和Q查询,事务)的相关文章

python3开发进阶-Django框架的ORM常用字段和参数

阅读目录 常用字段 字段合集 自定义字段 字段参数 关系参数 多对多的关联关系的三种方式 一.常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型,范围在 -2147483648 to 2147483647.  (最大十位) CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,

python3开发进阶-Django框架的自带认证功能auth模块和User对象的基本操作

阅读目录 auth模块 User对象 认证进阶 一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: authenticate()    提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数 如果认证信息有效,会返回一个  User  对象.authenticate()会在User 对象上设置一个属性来标识后端已经认证了该用户,且该信息

python3开发进阶-Django框架学习前的小项目(一个简单的学员管理系统)

''' 自己独立写一个学员管理系统 表结构: 班级表: -id -grade_name 学生表: -id -student_name -grade 关联外键班级表 老师表: -id -teacher_name -grades (多对多 关联班级表) ''' 在写小项目之前我们先复习一下小知识: 1. form表单提交数据的注意事项: 是form不是from,必须要有method和action 所有获取用户输入的表单标签要放在form表单里面,表单标签必须要有name属性 form表单必须要有su

python3开发进阶-Django视图(View)的常见用法

阅读目录 简述Django的View(视图) CBV和FBV Request对象和Response对象 Django组件(render,redirect)详解 一.简述Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. 无论视图本身包含什么逻辑,都要返回响应.代码写在哪里也无所谓,只要它在你当前项目目录下面. 除此之外

Django框架之数据库ORM框架

首先,我来介绍一下什么是ORM框架: O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思.在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据.ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程. django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改

在Python的Django框架中加载模版的方法

在Python的Django框架中加载模版的方法 为了减少模板加载调用过程及模板本身的冗余代码,Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板, 要使用此模板加载API,首先你必须将模板的保存位置告诉框架. 设置的保存文件就是settings.py. 如果你是一步步跟随我们学习过来的,马上打开你的settings.py配置文件,找到TEMPLATE_DIRS这项设置吧. 它的默认设置是一个空元组(tuple),加上一些自动生成的注释. TEMPLATE_DIRS =

Django 框架篇(五): ORM详细操作

 ORM之models.py  字段: 常用字段 : AutoField: 自增的整形字段,必填参数primary_key=True,则成为数据库的主键.无该字段时,django自动创建. 一个model不能有两个AutoField字段. IntegerField: 一个整数类型.数值的范围是 -2147483648 ~ 2147483647. CharField: 字符类型,必须提供max_length参数.max_length表示字符的长度. DateField: 日期类型,日期格式为YYY

Python的Django框架中的Context使用

Python的Django框架中的Context使用 一旦你创建一个 Template 对象,你可以用 context 来传递数据给它. 一个context是一系列变量和它们值的集合. context在Django里表现为 Context 类,在 django.template 模块里. 她的构造函数带有一个可选的参数: 一个字典映射变量和它们的值. 调用 Template 对象 的 render() 方法并传递context来填充模板: >>> from django.template

Python的Django框架中的Cookie相关处理

Python的Django框架中的Cookie相关处理 浏览器的开发者在很早的时候就已经意识到, HTTP's 的无状态会对Web开发者带来很大的问题,于是(cookies)应运而生. cookies 是浏览器为 Web 服务器存储的一小段信息. 每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的cookies 来看看它是怎么工作的. 当你打开浏览器并访问 google.com ,你的浏览器会给Google发送一个HTTP请求,起始部分就象这样: GET / HTTP/1.1 Host: