I have a CarType that has a ForeignKey BodyMaterial in my models.py:
class BodyMaterial(models.Model):
location = models.ForeignKey('CarType')
name = models.CharField(max_length=255)
class CarType(models.Model):
name = models.CharField(max_length=255)
default_body_material = models.ForeignKey(BodyMaterial, null = True, blank = True, default = "", limit_choices_to={'location__exact': 1})
BodyMaterial is an Inline in CarType in my admin.py:
class BodyMaterial_Inline(admin.StackedInline):
model = BodyMaterial
extra = 1
class CarType_Admin(admin.ModelAdmin):
inlines = [BodyMaterial_Inline]
admin.site.register(CarType, CarType_Admin)
I would like to filter the ForeignKey for default_body_material to show only the relevant BodyMaterials (the ones that appear/added on the same admin page). For example, I created a 2 seat CarType and in the same page added some BodyMaterials. Then I create an SVU CarType and some other BodyMaterials. When I go back to the 2 seat CarType, I would like to see only the relevant BodyMaterials in the drop-down for default_body_material.
I try to filter using limit_choices_to on the id. So I'm doing this using post_init because the id for the object in determined in runtime:
def setID(**kwargs):
instance = kwargs.get('instance')
default_body_material = instance._meta.get_field_by_name('default_body_material')[0]
default_body_material.limit_choices_to = {'location__exact': instance.id}
post_init.connect(setID, CarType)
Unfortunately, that does nothing. What am I missing? Is there a beter why of filtering ForeignKey for my purposes (this is probably very basic)?
Note that this question is only for the admin interface.
Just use a custom ModelForm
:
class CarTypeAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CarTypeAdminForm, self).__init__(*args, **kwargs)
# Can't limit it until instance has been saved at least once
if self.instance.pk:
self.fields['default_body_material'].queryset = \
self.fields['default_body_material'].queryset \
.filter(location=self.instance)
class CarTypeAdmin(admin.ModelAdmin):
form = CarTypeAdminForm
...