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)
一些其它写法
g)