Набор форм встроенной модели Django и форма встроенной модели обрабатывают инициалы по-разному

Я использую StackedInline для заполнения OneToOneField, но хочу сделать его необязательным, поэтому устанавливаю min_num=0 и extra = 0.

Я также хочу включить значения по умолчанию, когда пользователь нажимает кнопку «➕ Добавить еще».

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        kwargs['initial'] = {'hello': 'world'}

class MyInline(admin.StackedInline):
    form = MyForm
    extra = 0
    min_num=0

Это работает. Когда кто-то нажимает кнопку «➕ Добавить еще», поле hello заполняется world.

Я также хочу выполнить некоторую пользовательскую проверку, поэтому похоже, что мне нужно использовать BaseInlineFormSet. Я переместил исходный материал в MyFormSet.__init__

class MyFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if not self.forms:
            return
        self.forms[0].fields['hello'].initial = 'world'
        
    def clean(self):
        # My custom validation

class MyInline(admin.StackedInline):
    formset = MyFormSet
    extra = 0
    min_num=0

Но начальные значения больше не заполняются, когда пользователь нажимает кнопку «➕ Добавить еще», а только тогда, когда форма изначально отображается с extra = 1.

Есть ли что-то еще, что мне нужно сделать в MyFormSet, чтобы сохранить поведение MyForm?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
128
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема

Вы не можете попытаться установить свойство initial в __init__ вашего набора форм, поскольку self.forms[0] на тот момент даже не существует. Правильное место для этого (как в вашем первом) пример, в методе инициализации вашего MyForm.

Решение

Что вы можете сделать, так это использовать MyFormSet для реализации своей пользовательской проверки с помощью clean и использовать MyForm для добавления логики о значениях по умолчанию, а затем:

from django.forms import formset_factory

class MyInline(admin.StackedInline):
    form = Myform
    formset = MyFormSet
    extra = 0
    min_num=0

Спасибо за быстрый ответ! У меня не работает, к сожалению. Все еще не получаю значения по умолчанию с помощью кнопки. Я использую Django 1.11, если это что-то меняет.

frank 21.12.2020 02:32

О верно. Есть ли причина использовать такую ​​старую версию? Не знаю, что изменилось с 1.11. Будет намного проще получить поддержку в целом с более последней версией.

tim-mccurrach 21.12.2020 02:35

@frank, похоже, на самом деле все еще проще. Я обновил свой ответ.

tim-mccurrach 21.12.2020 02:40

О, идеально! Я даже не думал использовать оба параметра одновременно :D

frank 21.12.2020 02:42

И я не делал этого, пока не взглянул на то, что происходит под капотом, self.form передается на фабрику форм, а также self.formset.

tim-mccurrach 21.12.2020 02:44

Другие вопросы по теме