Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#23795 closed Bug (fixed)

Django form fields : limit_choices_to should not be mandatory with queryset

Reported by: artscoop Owned by: nobody
Component: Forms Version: 1.7
Severity: Release blocker Keywords: formfield, queryset, limit_choices_to
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hi,
I've found something that might be a bug, and which didn't happen with Django 1.6.
I have an admin definition which uses a custom form field (an ajax field for ForeignKey lookups which inherits from CharField), and changes the form as follows:

    def get_form(self, request, obj=None, **kwargs):
        form = super(ProfileAdmin, self).get_form(request, obj, **kwargs)
        if obj is not None:
            form.base_fields['picture'].queryset = obj.pictures.all()
        return form

This works well with Django 1.6 (and the queryset filtering is ok), but clashes with Django 1.7 code (*django/forms/models.py, 333, in BaseModelForm.init*)

            if hasattr(formfield, 'queryset'):
                limit_choices_to = formfield.limit_choices_to  # this attribute might not be a member of the field
                if limit_choices_to is not None:
                    if callable(limit_choices_to):
                        limit_choices_to = limit_choices_to()
                    formfield.queryset = formfield.queryset.complex_filter(limit_choices_to)

This fails with an AttributeError because Django assumes, without checking, that when a formfield is altered to use a queryset, it also uses a limit_choices_to attribute. This is not always true, it seems.
I see no error when instead of the custom field, I use a ModelChoiceField (this makes sense, ModelChoiceField always has a limit_choices_to field).

limit_choices_to = formfield.limit_choices_to

should be

limit_choices_to = getattr(formfield, 'limit_choices_to', None)

Change History (6)

comment:1 Changed 6 years ago by artscoop

Pull request for django/master made https://github.com/django/django/pull/3497, bug affects 1.7 and above.

comment:2 Changed 6 years ago by Tim Graham

Has patch: set
Needs tests: set
Triage Stage: UnreviewedAccepted

comment:3 Changed 6 years ago by Baptiste Mispelon

Needs tests: unset
Severity: NormalRelease blocker

comment:4 Changed 6 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:5 Changed 6 years ago by Baptiste Mispelon <bmispelon@…>

Resolution: fixed
Status: newclosed

In bfb11b95626f39e2f5e18d97d7761c6f93dcc1a9:

Fixed #23795 -- Fixed a regression in custom form fields

Custom form fields having a queryset attribute but no
limit_choices_to could no longer be used in ModelForms.

Refs #2445.

Thanks to artscoop for the report.

comment:6 Changed 6 years ago by Baptiste Mispelon <bmispelon@…>

In 606c57a132a1e1e680853c014efc41110ee75a80:

[1.7.x] Fixed #23795 -- Fixed a regression in custom form fields

Custom form fields having a queryset attribute but no
limit_choices_to could no longer be used in ModelForms.

Refs #2445.

Thanks to artscoop for the report.

Backport of bfb11b95626f39e2f5e18d97d7761c6f93dcc1a9 from master.

Conflicts:

django/forms/fields.py

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