Django Q 错误查询逻辑

Posted

技术标签:

【中文标题】Django Q 错误查询逻辑【英文标题】:Django Q bad query logic 【发布时间】:2014-03-25 08:07:48 【问题描述】:

我正在尝试创建一个具有“active_or_users”方法的管理器,以检索所有活动帐户或用户创建的所有帐户。活动帐户的开始日期可以是今天,也可以是过去某个时间,结束日期可以是未来某个时间。现在 active_or_users 方法有效,但是它返回相同对象的副本。它返回用户创建的活动作业的三个副本。这不太理想。

from django.db.models import Q
from django.db import models
from django.contrib.auth.models import User

class ActiveJobs(models.Manager):
    def active(self):
        return super(ActiveJobs, self).get_query_set().\
            filter(publications__publish_on__lte=date.today(),
                   publications__end_on__gt=date.today())

    def active_or_users(self, user):
        return super(ActiveJobs, self).get_query_set().\
            filter((Q(publications__publish_on__lte=date.today()) &
                    Q(publications__end_on__gt=date.today())) | Q(creator=user))

class Job(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(blank=True, null=True)
    creator = models.ForeignKey(User)
    objects = ActiveJobs()


class JobPublicationRecord(models.Model):
    job = models.ForeignKey('Job', related_name='publications')
    publish_on = models.DateField(auto_now=False)
    end_on = models.DateField(auto_now=False, auto_now_add=False,
                                blank=True, null=True)

【问题讨论】:

您是否尝试过使用distinct 方法? 我没有。我相信这会奏效。我只是很困惑为什么我会得到同一个对象三次? 因为每次查询都会返回一个实例。即:如果作业实例由用户创建,另一个作业实例也在指定的日期范围内。 噢噢噢噢噢。脑洞大开。是的,distinct 解决了这个问题。谢谢你们:D 【参考方案1】:

将 cmets 放入答案中

使用OR 查询,每次查询命中都会返回一个实例。即:如果作业是由用户创建的,则为一个实例,如果也在指定的日期范围内,则为同一作业的另一个实例,等等。

因此,要解决此问题,请将方法 active_or_users 更改为:

def active_or_users(self, user):
    return super(ActiveJobs, self).get_query_set().filter(
        (Q(publications__publish_on__lte=date.today()) &
         Q(publications__end_on__gt=date.today())) | Q(creator=user)).distinct()

【讨论】:

以上是关于Django Q 错误查询逻辑的主要内容,如果未能解决你的问题,请参考以下文章

django过滤器中的逻辑操作

如何在 django 查询中使用列表 [重复]

urls.py 中的 Django 时区逻辑和通用视图引发错误,但它是视图、字段还是我?

如何修复查询以获得错误的答案

Django 数据库操作

查询数据库时出现 Django 编码错误