Фильтрация ForeignKey по идентификатору объекта
У меня есть CarType, который имеет ForeignKey BodyMaterial в моих 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 является встроенным в CarType в моем 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)
Я хотел бы отфильтровать ForeignKey для default_body_material, чтобы показать только соответствующие BodyMaterials (те, которые появляются / добавляются на той же странице администратора). Например, я создал 2-местный CarType и на той же странице добавил несколько BodyMaterials. Затем я создаю SVU CarType и некоторые другие BodyMaterials. Когда я вернусь к 2-местному CarType, я хотел бы видеть только соответствующие BodyMaterials в раскрывающемся списке default_body_material.
Я пытаюсь фильтровать с помощью limit_choices_to по идентификатору. Итак, я делаю это с помощью post_init, потому что идентификатор объекта определяется во время выполнения:
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)
К сожалению, это ничего не делает. Что мне не хватает? Есть ли лучшая причина для фильтрации ForeignKey для моих целей (это, вероятно, очень просто)?
Обратите внимание, что этот вопрос только для интерфейса администратора.
2 ответа
Просто используйте кастом 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
...
Вы хотите посмотреть на переопределение функции queryset для вашего встроенного.