通过匹配布尔值来进行Django条件查询

时间:2016-09-20 12:37:16

标签: django django-queryset django-orm django-filter django-q

我知道有几种方法可以实现,即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 个答案:

答案 0 :(得分: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())))

OR

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())))