-
-
Save jgsogo/1731984 to your computer and use it in GitHub Desktop.
InlineAdmin mixin limiting the selection of related items according to criteria which can depend on the current parent object being edited.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from LimitedAdminInlineMixin import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
logger = logging.getLogger('commerce') | |
class LimitedAdminInlineMixin(object): | |
""" | |
InlineAdmin mixin limiting the selection of related items according to | |
criteria which can depend on the current parent object being edited. | |
A typical use case would be selecting a subset of related items from | |
other inlines, ie. images, to have some relation to other inlines. | |
Use as follows:: | |
class MyInline(LimitedAdminInlineMixin, admin.TabularInline): | |
def get_filters(self, obj): | |
return (('<field_name>', dict(<filters>)),) | |
""" | |
@staticmethod | |
def limit_inline_choices(formset, field, empty=False, **filters): | |
""" | |
This function fetches the queryset with available choices for a given | |
`field` and filters it based on the criteria specified in filters, | |
unless `empty=True`. In this case, no choices will be made available. | |
""" | |
assert formset.form.base_fields.has_key(field) | |
qs = formset.form.base_fields[field].queryset | |
if empty: | |
logger.debug('Limiting the queryset to none') | |
formset.form.base_fields[field].queryset = qs.none() | |
else: | |
qs = qs.filter(**filters) | |
logger.debug('Limiting queryset for formset to: %s', qs) | |
formset.form.base_fields[field].queryset = qs | |
def get_formset(self, request, obj=None, **kwargs): | |
""" | |
Make sure we can only select variations that relate to the current | |
item. | |
""" | |
formset = \ | |
super(LimitedAdminInlineMixin, self).get_formset(request, | |
obj, | |
**kwargs) | |
for (field, filters) in self.get_filters(obj): | |
self.limit_inline_choices(formset, field, **filters) | |
#if obj: | |
# self.limit_inline_choices(formset, field, **filters) | |
#else: | |
# self.limit_inline_choices(formset, field, empty=True) | |
return formset | |
def get_filters(self, obj): | |
""" | |
Return filters for the specified fields. Filters should be in the | |
following format:: | |
(('field_name', {'categories': obj}), ...) | |
For this to work, we should either override `get_filters` in a | |
subclass or define a `filters` property with the same syntax as this | |
one. | |
""" | |
return getattr(self, 'filters', ()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment