Django models ForeignKey and custom admin filters...
... or how to limit dynamic foreign key choices in both edit drop-down and admin filter.
The problem: Having a foreign key between models in django is really simple. For example:
class Question(models.Model):
# some fields here
class Answer(models.Model):
# some fields here
question = models.ForeignKey(Question)
from django.contrib.admin.filterspecs import FilterSpec, RelatedFilterSpec
class CustomFilterSpec(RelatedFilterSpec):
def __init__(self, *args, **kwargs):
super(CustomFilterSpec, self).__init__(*args, **kwargs)
self.lookup_choices = get_questions() #this method returns the dynamic list
FilterSpec.filter_specs.insert(0, (lambda f: bool(f.rel and hasattr(f, 'custom_filter_spec')), CustomFilterSpec))
class Answer(models.Model):
# some fields here
question = models.ForeignKey(Question)
question.custom_filter_spec = True # this is used to identify the fields which use the custom filter
Final word: The solutions is pretty simple and really easy to implement but should be used carefully. If your filtering method(in my case get_questions) is slow/resource consuming it may bring you troubles. Here is the place where and you should think about caching it. This is a place where a application cache can be used. Hope this will help you as much as it helped me.