Динамические поля в админке django из метода __init__ формы
У меня есть несколько моделей:
class Variation(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class VariationOption(models.Model):
value = models.CharField(max_length=100)
variation = models.ForeignKey(Variation, on_delete=models.CASCADE)
def __str__(self):
return self.value
class BaseProduct(models.Model):
name = models.CharField(max_length=100)
variations = models.ManyToManyField(Variation, blank=True)
class Product(models.Model):
base_product = models.ForeignKey(BaseProduct, on_delete=models.CASCADE, null=True, blank=True)
variation_options = models.ManyToManyField(VariationOption, null=True, blank=True)
Форма администратора, в которой я динамически добавляю поля в методе init:
class ProductAdminInlineForm(forms.ModelForm):
class Meta:
model = Product
exclude = ['variation_options']
def __init__(self, base_product, *args, **kwargs):
super(ProductAdminInlineForm, self).__init__(*args, **kwargs)
if base_product:
self.base_product = base_product
variations = self.base_product.variations.all()
for variation in variations:
field_name = f'variation_{variation.id}'
self.fields[field_name] = forms.ModelMultipleChoiceField(
queryset=VariationOption.objects.filter(variation=variation),
required=True,
widget=forms.CheckboxSelectMultiple,
label=variation.name
)
вот мои модели администратора:
class ProductInline(admin.TabularInline):
model = Product
exclude = ['variation_options']
form = ProductAdminInlineForm
class BaseProductAdmin(admin.ModelAdmin):
model = BaseProduct
list_display = ['__str__']
inlines = [ProductInline]
def get_formset_kwargs(self, request, obj, inline, prefix, **kwargs):
return {
**super().get_formset_kwargs(request, obj, inline, prefix),
'form_kwargs': {"base_product": obj},
}
Я пытаюсь получить динамические поля, которые я объявляю в методе ProductAdminInlineForm init на странице администратора, но похоже, что ProductInline не вызывает init для получения полей формы. Как я могу этого добиться? Я попытался переопределить методы get_fields и get_fieldset в классе ProductInline:
def get_fieldsets(self, request, obj=None):
fieldsets = super(ProductInline, self).get_fieldsets(request, obj)
if obj is not None:
variations = obj.variations.all()
for variation in variations:
field_name = f'variation_{variation.id}'
field = forms.ModelMultipleChoiceField(
queryset=VariationOption.objects.filter(variation=variation),
required=True,
widget=forms.CheckboxSelectMultiple,
label=variation.name
)
fieldsets[0][1]['fields'].append(field_name)
return fieldsets
но это не сработало, потому что поле не присутствует в Product Model:
Я все еще ищу решение, есть ли какие-нибудь новости?