Django ORM relatedmanager добавление значений по умолчанию к фильтрам

#django #filter #orm #django-queryset

#django #Фильтр #orm #django-набор запросов

Вопрос:

Неожиданные фильтры в 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
)
  

Если у меня есть только одна группа ответов на задание, и я ищу ее ответ с идентификатором 1, почему все остальные биты там фильтруются по internalquestion и ImageFile, и AudioFile и т.д.

Я ищу ответы в примечаниях к выпуску django, но они пусты. Надеюсь, кто-нибудь, кто обновился с 1.8 до 2.1, сталкивался с этим и может мне помочь?

Комментарии:

1. Есть ли у вас какие-либо пользовательские менеджеры моделей или запросы, устанавливающие значения по умолчанию для любой из этих моделей или полей взаимосвязи?

2. да… Я думаю, что это все. Также в классе JobResponse у меня есть medias = job_response_media() и objects = models.Manager() . Я предполагаю, что они вышли из строя и medias становится менеджером по умолчанию или что-то в этом роде. Странно, однако, что это происходит только в связанных запросах менеджера. Если я это сделаю JobResponse.objects.filter(pk=1) , все будет хорошо.

3. Вот часть документации, в которой обсуждаются менеджеры моделей для связанных полей: docs.djangoproject.com/en/2.1/topics/db/managers /…

4. Спасибо… и в этой части упоминается важность перечисления их по порядку, поскольку первый обрабатывается иначе, чем остальные. docs.djangoproject.com/en/2.1/topics/db/managers /…

Ответ №1:

Как указано в комментариях к исходному вопросу, проблема была связана с порядком указанных менеджеров. Был пользовательский Manager() , который использовался для фильтрации мультимедиа, и он каким-то образом попал в список перед значением по умолчанию objects = models.Manager()

Как упоминалось в документах для Model._default_manager :

… первый менеджер, с которым сталкивается Django (в том порядке, в котором они определены в модели), имеет особый статус…

Итак, исправление заключалось в изменении менеджеров в модели из…

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

Для…

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