Django F、Q 查询,事物,only、defer 及其他

1、F查询:

我们构造的过滤器 filter 只是将字段值与某个我们自己设定的常量做比较。如果需要用到对两个字段来比较,就感觉无从下手了

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

from django.db.models import F,Q
# 当查询条件来自于数据库的某个字段,这个时候就必须使用F
# 查询卖出数大于库存数的商品
res = models.Product.objects.filter(maichu__gt=F('kucun'))
# 将所有商品的价格提高100块
models.Product.objects.update(price=F('price')+100)
# 将所有商品的名字后面加一个爆款后缀
from django.db.models.functions import Concat
from django.db.models import Value

models.Product.objects.update(name=F('name')+'爆款') # 错误示范
models.Product.objects.update(name=Concat(F('name'),Value('爆款')))

注:Concat表示进行字符串的拼接操作,参数位置决定了拼接是在头部拼接还是尾部拼接,Value里面是要新增的拼接值

 

2、Q查询

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

# 当你的查询条件想以或的关系查询数据
models.Product.objects.filter(Q(name='变形金刚'),Q(price=999.99)) # 这样写默认还是and关系
models.Product.objects.filter(Q(name='变形金刚')|Q(price=999.99))
# Q与普通过滤条件混合使用
models.Product.objects.filter(Q(name='变形金刚'),price=100.00)

 

#查询 库存数是100 并且 卖出数不是0 的产品

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

 

可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。

同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

 

示例3:

查询产品名包含新款, 并且库存数大于60的

models.Product.objects.filter(Q(kucun_gt=60),name_contains='新款')

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

 

Q查询进阶操作(******)
# 先实例化一个Q对象
q = Q()
q.connector = 'or'    #当存在这步操作后,就可以将其默认关系改变为  or
q.children.append(('name','jason'))     #name=jason
q.children.append(('price',666))       #price=666
# q对象支持直接放在filter括号内
models.User.objects.filter(q)     # q对象默认也是and关系

 

 

 

3、事物

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

开启事务处理:

try:

    with transaction.atomic():

    #创建一条订单数据
    models.Order.objects.create(num='110',product_id=1,count=1)

    #能执行成功

    models.Product.objects.filter(id=1).update(kucun=F('kucun')-1,maichu=F('maichu')+1)

except Exception as e:

  print(e)

 

补充:update() 与 save() 的区别:

两者都是对数据的修改保存操作,但是save()函数是将数据列的全部数据项全部重新写一遍,而update()则是针对修改的项进行针对的更新效率高耗时少,所以以后对数据的修改保存用update()

 

4、only 与 defer 

defer('id','name'):取出对象,字段除了id和name都有
only('id','name'):取的对象,只有id和name
res =   models.Product.objects.only(id,name)

for i in res:

  # 查询不在的字段,会再次查询数据库,造成数据库压力

  print(i.name)

 

5、choice字段


choices字段
class User(models.Model):
  name = models.CharField(max_length=32)
  password = MyCharField(max_length=32)
  choices = ((1,'重点大学'),(2,'普通本科'),(3,'专科'),(4,'其他'))
  education = models.IntegerField(choices=choices)

user_obj 是实例化出来的一个对象。

user_obj.education # 拿到的是数字
user_obj.get_education_display() # 固定用法 获取choice字段对应的注释

可见education字段保存了两个信息,一个为数字,一个为对应的注释。

 

              

     

 

posted on 2019-06-14 14:40  michael-chang  阅读(213)  评论(0编辑  收藏  举报

导航