Opened 5 years ago

Last modified 5 years ago

#30000 closed Bug

Passing QuerySet constructed with .union() causes ModelMultipleChoiceField to return wrong values — at Initial Version

Reported by: Thomas Hamann Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: queryset union
Cc: Prabakaran Kumaresshan Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a form that displays large lists of selectable records using ModelMultipleChoiceFields. These fields need to show a predetermined list of records, obtained through some database queries performed within the Form's class init block.
The QuerySet required is constructed by reaching through a few ForeignKey relationships to retrieve the required records and then using the .union() method to assemble the QuerySet.
e.g.:

# Retrieve original record:
 base = BaseModel.objects.filter(source_name=source_name).first()
# Get related record via ForeignKey relationship:
related_record = base.related_record
# related_record.other_related_things has ManyToMany relationship to another Model (one or more records).
# So get them:
other_related_things = related_record.other_related_things.all()
# Loop through these:
union_queryset = None 
for other_related_thing in other_related_things:
    # Each other_related_thing has a set of SelectableRecords associated with it, via a ForeignKey relationship from the latter model to the former one. This gets that QuerySet:
    other_related_thing_queryset = other_related_thing.selectablerecords_set.all()
    # Build union_queryset:
    if union_queryset is None:
        union_queryset = other_related_thing_queryset
    else:
        union_queryset = union_queryset_object.union(other_related_thing_queryset)
        # The resulting union_queryset is a unified queryset containing all of the required fields. 
        # If only one other_related_thing exists, the result of evaluating the union_queryset QuerySet ought to be the 
        # same as the result of evaluating SelectableRecords.objects.all()

However, when I pass the union_queryset to my ModelMultipleChoiceFields, validating the form returns all of the records contained in union_queryset instead of the records selected on the form. The form displays correctly.

The code used for this is:

self.fields['selectable_records'] = forms.ModelMultipleChoiceField(queryset=union_queryset, required=False,
                                                    label='Selectable records',
                                                    widget=forms.CheckboxSelectMultiple)

Do take note that the documentation for the .union() method (here) indicates there are some limits to the QuerySet returned, and I assume my problem has to do with this.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top