Skip to content

F和Q查询

Q

官档:https://docs.djangoproject.com/zh-hans/5.0/topics/db/queries/#complex-lookups-with-q-objects

python
# 同时支持用户名/手机号/邮箱+密码登录
# 下面两种写法是等价的
UserInfo.objects.filter(Q(username='root1') | Q(email='root@root.com') | Q(mobile='182111011111'), Q(password="123")).first()
UserInfo.objects.filter((Q(username='root1') | Q(email='root@root.com') | Q(mobile='182111011111')) & Q(password='123')).first()

针对choices字段的查询

来一个业务场景,就是页面中针对用户信息列表页,只有一个搜索框,对全字段内容进行搜索的话,下面的视图函数可以实现这个需求.

python
from django.db import models

class UserInfo(models.Model):
    """用户信息"""
    username = models.CharField(max_length=32, verbose_name='用户名')
    password = models.CharField(max_length=32, verbose_name='密码')
    email = models.EmailField(verbose_name='邮箱')
    nickname = models.CharField(max_length=32, verbose_name='昵称')
    mobile = models.CharField(max_length=11, verbose_name='手机号')
    gender_choices = ((0, '女'), (1, '男'))
    gender_q_map = {"男": 1, '女': 0}
    gender = models.CharField(max_length=1, choices=gender_choices, default=1, verbose_name='性别')
    level_choices = ((0, '青铜'), (1, '白银'), (2, '黄金'))
    level_q_map = {"青铜": 0, '白银': 1, '黄金': 2}
    level = models.CharField(max_length=1, choices=level_choices, default=1, verbose_name='级别')
    def __str__(self):
        return self.username
python
from django.db.models import F, Q
from api.models import UserInfo
def index(request):
    # 获取用户输入的值,这个值要和数据库中所有的字段进行匹配,关系是or
    text = request.GET.get("keyword", '')
    if text:
        q = Q()
        q.connector = 'or'
        q.children.append(("username", text))
        q.children.append(("password", text))
        q.children.append(("email", text))
        q.children.append(("nickname__contains", text))  # 包含/in/大于小于等等都能写的
        q.children.append(("mobile", text))
        # 对于choices字段,不能直接写,因为数据库存的是数字,但用户输入的是对应的显示文本,
        # 所以这里要根据模型类中提前定义好的map字典进行一个映射文本->数字的映射处理
        # 本质上是字典的get取值
        q.children.append(("gender", UserInfo.gender_q_map.get(text))) 
        q.children.append(("level", UserInfo.level_q_map.get(text)))
        obj = UserInfo.objects.filter(q)
        print(obj)

一些其它写法

1832669374037622784.png g)