一、F查询与Q查询
1.1 F查询:
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个我们自己设定的常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
示例1:
查询出卖出数大于库存数的商品
# Create your tests here. if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day60test.settings") import django django.setup() from app01 import models # 前提是要导入这个F与Q from django.db.models import F,Q # 为什么需要F与Q查询 # 前面的filter里面都是用字段与一个常量比较, # 如果要比较的是两个字段呢,就需要借助F函数了 # 1. 查询卖出数大于库存数的商品 res1 = models.Product.objects.filter(maichu__gt=F('kucun')) print(res1) # 拿到卖出大有库存的对象 <QuerySet [<Product: 商品对象的名字:上衣>, <Product: 商品对象的名字:裤子>]>
# 2.将所有的商品价格提高100块
res2 = models.Product.objects.update(price=F('price')+100)
print(res2)
# 3.将所有的名字后面加上一个爆款后缀 需要导入Concat
from django.db.models.functions import Concat
from django.db.models import Value
res = models.Product.objects.update(name=Concat(F('name'),Value('爆款')))
1.2 Q查询:
filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如ORM语句),你可以使用Q对象。
示例1:
# 当你的查询条件想以and |或的关系查询数据是
res = models.Product.objects.filter(Q(name='上衣爆款爆款'),Q(price=299))
print(res) # and必须是同时满足才能进行查取 不然得到结果为空
# ,是and 的关系 必须同时满足 两个条件 那么或怎么查呢
# res1 = models.Product.objects.filter(Q(name='上衣爆款爆款')|Q(price=21088))
# print(res1)
# 或是只要有一方Q(name=)或者Q(price=) 都可以查到我们的目标对象 要么都没 要么都有 要一方有
# Q查询进价操作(*****)
# 第一 先实列化一个Q对象
q = Q()
q.connector = 'or' # 里面是默认and关系
q.children.append(('name','jason'))
q.children.append(('price', 666))
res = models.Product.objects.filter(q)
print(q) # q对象样式默认关系
# (or: ('name', 'jason'), ('price', 666))
1.3 事务
事务
from django.db import transaction
with transaction.atomic():
# 这里写多个数据库操作
print('其他逻辑代码')
1.4 自定字段
自定义字段类型
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):
return 'char(%s)'%self.max_length
class User(models.Model):
name = models.CharField(max_length=32)
password = MyCharField(max_length=32)
only与defer
# 两者是相反的
res = models.User.objects.only('name')
1.5 choices= choices
# 自定义字段: class MycharFild(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 class User(models.Model): name = models.CharField(max_length=32) password = MycharFild(max_length=32) choices = ((1,'重点大学'),(2,'普通本科'),(3,'专科'),(4,'其他')) education = models.IntegerField(choices=choices) user_obj.education # 拿到的是数字 user_obj.get_education_display() # 固定用法 获取choice字段对应的注释
补充图书管理系统: