diff options
| author | Christopher Adams <christopher.r.adams@gmail.com> | 2014-02-01 14:23:31 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-02-11 14:05:12 -0500 |
| commit | eefc88feefec0c3685bfb102714530b751b4ae90 (patch) | |
| tree | 3cab4b02c13b76b6355d475d91ca2e157a126b18 /django/forms | |
| parent | a718fcf201b04ba254e9073be82f51ae1ae3a853 (diff) | |
Fixed #2445 -- Allowed limit_choices_to attribute to be a callable.
ForeignKey or ManyToManyField attribute ``limit_choices_to`` can now
be a callable that returns either a ``Q`` object or a dict.
Thanks michael at actrix.gen.nz for the original suggestion.
Diffstat (limited to 'django/forms')
| -rw-r--r-- | django/forms/fields.py | 11 | ||||
| -rw-r--r-- | django/forms/models.py | 13 |
2 files changed, 23 insertions, 1 deletions
diff --git a/django/forms/fields.py b/django/forms/fields.py index 1ce36c199c..629aa69c5d 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -170,6 +170,17 @@ class Field(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 37a1b93bf5..a0b47e64b4 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -324,6 +324,15 @@ class BaseModelForm(BaseForm): self._validate_unique = False super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data, error_class, label_suffix, empty_permitted) + # 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 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): """ @@ -1082,7 +1091,8 @@ class ModelChoiceField(ChoiceField): def __init__(self, queryset, empty_label="---------", cache_choices=False, required=True, widget=None, label=None, initial=None, - help_text='', to_field_name=None, *args, **kwargs): + help_text='', to_field_name=None, limit_choices_to=None, + *args, **kwargs): if required and (initial is not None): self.empty_label = None else: @@ -1094,6 +1104,7 @@ class ModelChoiceField(ChoiceField): Field.__init__(self, required, widget, label, initial, help_text, *args, **kwargs) self.queryset = queryset + self.limit_choices_to = limit_choices_to # limit the queryset later. self.choice_cache = None self.to_field_name = to_field_name |
