1
votes

Unexpected filters in SQL for related manager. Filters appear to be on fields where I've set a default value in their declaration in the model.

We've upgraded from Python 2.7 / Django 1.8 to Python 3.6 / Django 2.1 and have started seeing this unexpected behaviour in our ORM queries.

Given the models

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
)

If I've just got a single job response group, and I'm looking for its response with and ID of 1, why are all the other bits in there filtering on internalquestion and imageFile, and audioFile, etc.

I'm looking for answers in the django release notes, but coming up empty. Hopefully someone who's upgraded from 1.8 to 2.1 has come across this and can help me out?

1
Do you have any custom model managers or query set defaults for any of these models or relationship fields? - schillingt
yep... I think that's it. Also in the JobResponse class I have medias = job_response_media() and objects = models.Manager(). I'm guessing they are out of order and medias is becoming the default manager or something like that. It is odd though that it only happens on the Related Manager queries. If I do JobResponse.objects.filter(pk=1), all is well. - Justin H.
Here's the part of the documentation that discusses the model managers for related fields: docs.djangoproject.com/en/2.1/topics/db/managers/… - schillingt
thanks... and this part mentions the importance of listing them in order as the first one is treated differently than the rest. docs.djangoproject.com/en/2.1/topics/db/managers/… - Justin H.

1 Answers

2
votes

As specified in the comments to the original question, the issue was due to the order of the specified managers. There was a custom Manager() that was being used to filter out media and it somehow got listed before the default objects = models.Manager()

As mentioned in the docs for Model._default_manager:

...the first Manager Django encounters (in the order in which they’re defined in the model) has a special status...

So the fix was changing the managers in the model from...

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

to...

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