【问题标题】:Django ORM relatedmanager adding defaults to filtersDjango ORM相关管理器为过滤器添加默认值
【发布时间】:2019-08-17 08:11:43
【问题描述】:

SQL 中针对相关经理的意外过滤器。过滤器似乎位于我在模型声明中设置了默认值的字段上。

我们已从 Python 2.7 / Django 1.8 升级到 Python 3.6 / Django 2.1,并开始在我们的 ORM 查询中看到这种意外行为。

给定模型

JobResponseGroup
 - respondent

JobResponse
 - job_response_group
 - job_info_request
 - answer
 - audofile
 - videofile
 - imagefile

JobInfoRequest
 - question_text
 - internal_question (default=0)
print(jrg.jobresponse_set.filter(pk=1).values('id').query)

SELECT 
"job_jobresponse"."id" 

FROM 
"job_jobresponse" 
INNER JOIN "jobInfoRequest" ON ("job_jobresponse"."jobInfoRequest_id" = "jobInfoRequest"."id") 

WHERE (((NOT ("job_jobresponse"."audioFile" =  AND "job_jobresponse"."audioFile" IS NOT NULL) AND "job_jobresponse"."audioFile" IS NOT NULL) OR (NOT ("job_jobresponse"."videoFile" =  AND "job_jobresponse"."videoFile" IS NOT NULL) AND "job_jobresponse"."videoFile" IS NOT NULL) OR (NOT ("job_jobresponse"."imageFile" = ) AND "job_jobresponse"."imageFile" IS NOT NULL) OR (NOT ("job_jobresponse"."imageFile2" = ) AND "job_jobresponse"."imageFile2" IS NOT NULL)) AND "jobInfoRequest"."internalQuestion" = 0 AND 

"job_jobresponse"."group_id" = 16212728 
AND "job_jobresponse"."id" = 1
)

如果我只有一个工作响应组,并且我正在寻找其 ID 为 1 的响应,那么为什么其中的所有其他位都过滤 internalquestion 和 imageFile 以及 audioFile 等。

我正在 django 发行说明中寻找答案,但结果是空的。希望从 1.8 升级到 2.1 的人遇到过这个问题并可以帮助我吗?

【问题讨论】:

  • 您是否有任何这些模型或关系字段的自定义模型管理器或查询集默认值?
  • 是的...我想就是这样。同样在 JobResponse 类中,我有 medias = job_response_media()objects = models.Manager()。我猜他们出了问题,medias 正在成为默认经理或类似的东西。奇怪的是它只发生在相关管理器查询上。如果我这样做JobResponse.objects.filter(pk=1),一切都很好。
  • 这里是讨论相关领域模型管理器的文档部分:docs.djangoproject.com/en/2.1/topics/db/managers/…
  • 谢谢...这部分提到了按顺序列出它们的重要性,因为第一个的处理方式与其他的不同。 docs.djangoproject.com/en/2.1/topics/db/managers/…

标签: django filter orm django-queryset


【解决方案1】:

如原始问题的 cmets 中所述,问题是由于指定经理的顺序造成的。有一个自定义的 Manager() 被用来过滤媒体,它以某种方式被列在默认的 objects = models.Manager() 之前。

Model._default_manager 的文档中所述:

...第一个 Django 遇到的 Manager(按照它们在模型中定义的顺序)具有特殊状态...

因此,解决方法是将模型中的管理器从...更改为...

medias = CustomMediaManager()
objects = models.Manager()

到...

objects = models.Manager()
medias = CustomMediaManager()

【讨论】:

    猜你喜欢
    • 2011-03-05
    • 2016-04-08
    • 2015-07-09
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2018-07-15
    相关资源
    最近更新 更多