Use QuestionAssignment.order where we expect it#2743
Conversation
There was a problem hiding this comment.
Do we want to have tests that check this ordering? I think that we decided in previous cases that ordering is something that is usually just right if we have the correct Meta.ordering set, but I feel that this is not the case here
There was a problem hiding this comment.
I agree that this is a bit more tricky here, and we should add a test. The wrong order of questions can make a questionnaire almost unusable.
richardebeling
left a comment
There was a problem hiding this comment.
Changes here lgtm, although I can definitely see that people will stumble over this again in the future. Let's discuss options in person some time (I'm thinking of asking django to respect M2M ordering, I feel like this is a reasonable ask, and maybe building some workaround in the meantime)
Closes #2741
When we introduced
QuestionAssignmentwe moved theorderfield fromQuestiontoQuestionAssignment. Semantically, this makes sense, because the same question might be ordered differently in different questionnaires. However, specifying an ordering on a through-model like this does not result in Django ordering the related instances as we expect (see https://code.djangoproject.com/ticket/30460). Instead, the order of the related model is used, which in our case (onQuestion) was unspecified, so the database just returned some arbitrary order.The fix is to not iterate over
questionnaire.questionsand instead prefer going viaquestionnaire.question_assignments. This ensures that theQuestionAssignmentordering is used. Another option would be to always prefetch with customPrefetchobjects likePrefetch("questions", queryset=Question.objects.order_by("assignments")). However, this seems less robust then explicitly going via assignments in the right places and also uses theorder_by("through-model")hack from the Django ticket which, as far as I can tell, is not documented.The places from the issue seem to be fixed by this PR. I checked for other places by searching for the strings
.questionsandquestions".