Django 通过匹配布尔值进行条件查询
Posted
技术标签:
【中文标题】Django 通过匹配布尔值进行条件查询【英文标题】:Django conditional query by matching boolean values 【发布时间】:2017-01-28 09:23:50 【问题描述】:我知道有几种方法可以实现,即 if/else 查询集、条件查询集、Q、聚合等。我基于这些提出了一些选项,但想知道最佳方法和建议.
Sudo 代码在我想要实现的目标下方。应用程序将传递布尔值的查询字符串,如下所示,即 True 或 False,如果一个用户根据查询字符串值和数据库数据有更多匹配项,则他们的排序将高于其他用户。
SELECT * from userdetails
if sun_morn is true then match_count++
if sun_day is true then match_count++
if sun_afternoon is true then match_count++
if sun_afternoon is true then match_count++
order_by match_count LIMIT by 10;
结果是显示匹配任何一个布尔值的所有用户,然后将匹配最多的用户排序在查询集的顶部。
在@Aison 代码的帮助下,关闭但无法正常工作:
""" /endpoint?sunmorn=1&sunday=0&sunafternoon=0&sunnight=1&monmorn=1&monday=0&monafternoon=0&monnight=1
&tuesmorn=1&tuesday=0&tuesafternoon=0&tuesnight=1&wedmorn=1&wedday=0&wedafternoon=0&wednight=1
&thursmorn=1&thursday=0&thursafternoon=0&thursnight=1&frimorn=1&friday=0&friafternoon=0&frinight=1
&satmorn=1&satday=0&satafternoon=0&satnight=1 """
queryset = queryset.aggregate(match_count=Sum(
Case(When(sun_morn | sun_day | sun_afternoon | sun_night,
then=1), output_field=IntegerField())
),
)
models.py
from django.conf import settings
from django.db import models
class userdetail(models.Model):
username = models.OneToOneField(settings.AUTH_USER_MODEL)
# removed extra fields as not needed for example
sun_morn = models.BooleanField(default=False, null=False, blank=False)
sun_day = models.BooleanField(default=False, null=False, blank=False)
sun_afternoon = models.BooleanField(default=False, null=False, blank=False)
sun_night = models.BooleanField(default=False, null=False, blank=False)
mon_morn = models.BooleanField(default=False, null=False, blank=False)
mon_day = models.BooleanField(default=False, null=False, blank=False)
mon_afternoon = models.BooleanField(default=False, null=False, blank=False)
mon_night = models.BooleanField(default=False, null=False, blank=False)
tues_morn = models.BooleanField(default=False, null=False, blank=False)
tues_day = models.BooleanField(default=False, null=False, blank=False)
tues_afternoon = models.BooleanField(default=False, null=False, blank=False)
tues_night = models.BooleanField(default=False, null=False, blank=False)
wed_morn = models.BooleanField(default=False, null=False, blank=False)
wed_day = models.BooleanField(default=False, null=False, blank=False)
wed_afternoon = models.BooleanField(default=False, null=False, blank=False)
wed_night = models.BooleanField(default=False, null=False, blank=False)
thurs_morn = models.BooleanField(default=False, null=False, blank=False)
thurs_day = models.BooleanField(default=False, null=False, blank=False)
thurs_afternoon = models.BooleanField(default=False, null=False, blank=False)
thurs_night = models.BooleanField(default=False, null=False, blank=False)
fri_morn = models.BooleanField(default=False, null=False, blank=False)
fri_day = models.BooleanField(default=False, null=False, blank=False)
fri_afternoon = models.BooleanField(default=False, null=False, blank=False)
fri_night = models.BooleanField(default=False, null=False, blank=False)
sat_morn = models.BooleanField(default=False, null=False, blank=False)
sat_day = models.BooleanField(default=False, null=False, blank=False)
sat_afternoon = models.BooleanField(default=False, null=False, blank=False)
sat_night = models.BooleanField(default=False, null=False, blank=False)
def __unicode__(self):
return u'%s' % self.username
【问题讨论】:
还有你的问题吗? 【参考方案1】:你需要的是Conditional aggregation
userdetails.objects.aggregate(
match_count =Sum(
Case(When(sun_morn | sun_day | sun_afternoon | sun_afternoon,
then=1),output_field=IntegerField())
),
)
编辑
如果你在字段中存储 unicode 或 str,你可以使用:
userdetail.objects.aggregate(
match_count=Sum(
Case(
When(sun_morn=True, then=1),
When(sun_day=True, then=1),
When(sun_afternoon=True, then=1),
output_field=IntegerField())))
或
userdetail.objects.aggregate(
match_count=Sum(
Case(When(
Q(sun_morn=True) | Q(sun_day=True) |
Q(sun_afternoon=True), then=1),
output_field=IntegerField())))
【讨论】:
感谢 Aison,看起来不错,但我看到一个错误:|: 'unicode' and 'unicode' 的操作数类型不受支持 感谢 Windsor,但我现在看到错误:__init__() 将 Q 对象或查找作为关键字参数 感谢 Windsooon,现在我看到错误:'bool' 对象不可迭代 如果我查询数据库字段,我也会收到错误:unhashable type 请参阅上面的更多编辑。 请添加你的model.py以上是关于Django 通过匹配布尔值进行条件查询的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch (DSL 布尔查询 过滤器 排序 高亮显示