Использование Inline в ModelForm в Django Admin

Я хочу проверить поле "многие ко многим" в админке Django, переопределив метод clean.

Эта тема дает способ сделать это, создав ModelForm и затем выполнив очистку там. Однако моя проблема заключается в том, что поле "многие ко многим" является инлайн-полем, т. е. вместо виджета, в котором нужно выбрать несколько элементов, у меня есть табличное инлайн-поле.

Я хотел бы узнать, знает ли кто-нибудь, как добавить инлайны в ModelForm, чтобы я мог сделать очистку и валидацию. Я видел, как люди говорили о inlineformset_factory, но это всегда относилось к views.py, а не к админке (и я не могу понять, как мне вообще переопределить метод clean).

Я добавил часть своего кода ниже:

class ProductVariantForm(ModelForm):
    class Meta:
        model = ProductVariant

        fields = [  'name',
                    'price',
                 ]

        # I then want to be able to add something like
        # inlines = [OptionValueInline,]
        # for the inline many-to-many field. 

    def clean(self):
        # Check if list of option_values is ok.

class ProductVariantAdmin(admin.ModelAdmin):
    form = ProductVariantForm

Добавление инлайна - это функция самого администратора. Смотрите этот документ для получения дополнительной информации об инлайнах. На самом деле, вы не можете добавить инлайн в обычную форму (или ModelForm).

Для проверки достоверности данных в инлайн-форме можно использовать свойство form класса InlineModelAdmin. Таким образом, вы сможете получить прямой доступ к методу clean инлайн-формы.

Подробнее, он разделен таким образом, потому что инлайны - это отдельная форма в терминах Django, касающаяся разных данных и выполняющая отдельные запросы. Все они передаются в одном HTTP-запросе, но это все, что их объединяет. Поэтому не имеет смысла использовать main ModelForm для инлайн-данных.

Мое решение проблемы основано на этом посте.

class ProductVariantOptionValueInlineFormSet(BaseInlineFormSet):
    def clean(self):
        super().clean()
        data = self.cleaned_data
        # do whatever validation on data here

class ProductVariantOptionValueInline(admin.TabularInline):
    model = ProductVariant.option_values.through
    formset = ProductVariantOptionValueInlineFormSet

class ProductVariantAdmin(admin.ModelAdmin):
    inlines = [
        ProductVariantOptionValueInline,
    ]

    exclude = ('option_values',)
Вернуться на верх