summaryrefslogtreecommitdiff
path: root/django/contrib/admin
diff options
context:
space:
mode:
authorChristopher Adams <christopher.r.adams@gmail.com>2014-02-01 14:23:31 -0500
committerTim Graham <timograham@gmail.com>2014-02-11 14:05:12 -0500
commiteefc88feefec0c3685bfb102714530b751b4ae90 (patch)
tree3cab4b02c13b76b6355d475d91ca2e157a126b18 /django/contrib/admin
parenta718fcf201b04ba254e9073be82f51ae1ae3a853 (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/contrib/admin')
-rw-r--r--django/contrib/admin/options.py5
-rw-r--r--django/contrib/admin/utils.py12
-rw-r--r--django/contrib/admin/widgets.py5
3 files changed, 14 insertions, 8 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index e3c3e8e57e..7b0dd8ebcb 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -240,7 +240,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
if related_admin is not None:
ordering = related_admin.get_ordering(request)
if ordering is not None and ordering != ():
- return db_field.rel.to._default_manager.using(db).order_by(*ordering).complex_filter(db_field.rel.limit_choices_to)
+ return db_field.rel.to._default_manager.using(db).order_by(*ordering)
return None
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
@@ -383,6 +383,9 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
# ForeignKeyRawIdWidget, on the basis of ForeignKey.limit_choices_to,
# are allowed to work.
for l in model._meta.related_fkey_lookups:
+ # As ``limit_choices_to`` can be a callable, invoke it here.
+ if callable(l):
+ l = l()
for k, v in widgets.url_params_from_lookup_dict(l).items():
if k == lookup and v == value:
return True
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index 0b74a6e75f..a2f2e9fa7b 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -459,17 +459,17 @@ def get_limit_choices_to_from_path(model, path):
""" Return Q object for limiting choices if applicable.
If final model in path is linked via a ForeignKey or ManyToManyField which
- has a `limit_choices_to` attribute, return it as a Q object.
+ has a ``limit_choices_to`` attribute, return it as a Q object.
"""
-
fields = get_fields_from_path(model, path)
fields = remove_trailing_data_field(fields)
- limit_choices_to = (
+ get_limit_choices_to = (
fields and hasattr(fields[-1], 'rel') and
- getattr(fields[-1].rel, 'limit_choices_to', None))
- if not limit_choices_to:
+ getattr(fields[-1].rel, 'get_limit_choices_to', None))
+ if not get_limit_choices_to:
return models.Q() # empty Q
- elif isinstance(limit_choices_to, models.Q):
+ limit_choices_to = get_limit_choices_to()
+ if isinstance(limit_choices_to, models.Q):
return limit_choices_to # already a Q
else:
return models.Q(**limit_choices_to) # convert dict to Q
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index f527d72f3f..f501ffb1a8 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -180,7 +180,10 @@ class ForeignKeyRawIdWidget(forms.TextInput):
return mark_safe(''.join(output))
def base_url_parameters(self):
- return url_params_from_lookup_dict(self.rel.limit_choices_to)
+ limit_choices_to = self.rel.limit_choices_to
+ if callable(limit_choices_to):
+ limit_choices_to = limit_choices_to()
+ return url_params_from_lookup_dict(limit_choices_to)
def url_parameters(self):
from django.contrib.admin.views.main import TO_FIELD_VAR