From bfb11b95626f39e2f5e18d97d7761c6f93dcc1a9 Mon Sep 17 00:00:00 2001 From: Baptiste Mispelon Date: Wed, 12 Nov 2014 21:18:11 +0100 Subject: 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. --- django/forms/fields.py | 11 ----------- django/forms/models.py | 17 +++++++++++++---- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'django/forms') diff --git a/django/forms/fields.py b/django/forms/fields.py index 81b3e2f4f9..950f9481a3 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -181,17 +181,6 @@ class Field(six.with_metaclass(RenameFieldMethods, object)): """ return {} - def get_limit_choices_to(self): - """ - Returns ``limit_choices_to`` for this form field. - - If it is a callable, it will be invoked and the result will be - returned. - """ - if callable(self.limit_choices_to): - return self.limit_choices_to() - return self.limit_choices_to - def has_changed(self, initial, data): """ Return True if data differs from initial. diff --git a/django/forms/models.py b/django/forms/models.py index acb7f91a76..b560ee84a9 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -328,11 +328,9 @@ class BaseModelForm(BaseForm): # Apply ``limit_choices_to`` to each field. for field_name in self.fields: formfield = self.fields[field_name] - if hasattr(formfield, 'queryset'): - limit_choices_to = formfield.limit_choices_to + if hasattr(formfield, 'queryset') and hasattr(formfield, 'get_limit_choices_to'): + limit_choices_to = formfield.get_limit_choices_to() 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) def _get_validation_exclusions(self): @@ -1133,6 +1131,17 @@ class ModelChoiceField(ChoiceField): self.choice_cache = None self.to_field_name = to_field_name + def get_limit_choices_to(self): + """ + Returns ``limit_choices_to`` for this form field. + + If it is a callable, it will be invoked and the result will be + returned. + """ + if callable(self.limit_choices_to): + return self.limit_choices_to() + return self.limit_choices_to + def __deepcopy__(self, memo): result = super(ChoiceField, self).__deepcopy__(memo) # Need to force a new ModelChoiceIterator to be created, bug #11183 -- cgit v1.3