Django Duplicate ModelForm

Мне интересно, есть ли простой способ создания «дубликата» ModelForm в Django, т.е. формы, предварительно заполненной содержимым существующего экземпляра модели (за исключением определенных полей, таких как уникальные), но создает новый экземпляр при сохранении.

Я думал о том, чтобы предоставить экземпляр в ModelForm, чтобы данные были предварительно заполнены, как в форме «редактировать», а затем установить для экземпляра значение «Нет» перед сохранением, но это дает «объект NoneType» не имеет атрибута «pk '" ошибка при вызове .save() в форме. Кажется, что действие по предоставлению экземпляра при построении формы создает некоторую зависимость от того, будет ли он там в конце.

У меня возникли проблемы с поиском решения этой проблемы, но я не могу представить, чтобы «дублированная» форма была слишком уникальной, поэтому, может быть, я упускаю что-то простое?

Любая помощь будет оценена по достоинству.


person oogles    schedule 31.08.2010    source источник
comment
Ты когда-нибудь находил работоспособное решение, ОП?   -  person pdoherty926    schedule 09.04.2019
comment
Это было некоторое время назад (и несколько версий Django) назад, и мы так и не реализовали эту функцию. Так что нет, я никогда не останавливался на решении. Хотя ответ @Pydev, по-видимому, не работал у меня в то время, это может быть другая история в более новой версии Джанго. Однако это также сопряжено с риском копирования слишком большого количества, поскольку вы начинаете с полностью заполненного экземпляра модели. Опять же, может быть, это поведение, которое вы хотите.   -  person oogles    schedule 10.04.2019
comment
Если бы я попробовал это снова сегодня, я бы, вероятно, попробовал что-то вроде @Manoj answer. Форма знает поля, которые она содержит, поэтому универсальное решение, которое извлекает эти поля из данного экземпляра и использует их для заполнения initial, не должно быть слишком сложным. Может быть, как метод фабричного класса, например. MyForm.as_duplicate(data, instance)?   -  person oogles    schedule 10.04.2019
comment
Спасибо за продолжение! Я закончил делать что-то очень похожее на то, что вы описали здесь. Метод класса в модели, который обрабатывает дублирование, и подклассовую версию моего WidgetUpdateView, которая использует метод дублирования для замены нового экземпляра в form_valid.   -  person pdoherty926    schedule 10.04.2019


Ответы (2)


Я думаю, что вам нужен способ заполнить начальные значения для полей в форме. Лучший способ добиться этого — создать словарь начальных значений (с ключом по имени поля) из существующего экземпляра и передать его в форму.

Что-то вроде этого:

class AddressForm(forms.ModelForm):
    class Meta:
        model = Address

# Inside view:
address = Address.object.get(**conditions)
initial = dict()
for field in ('state', 'zipcode'): # Assuming these are the fields you want to pre-fill
    initial[field] = getattr(address, field)

form = AddressForm(initial = initial)
person Manoj Govindan    schedule 31.08.2010

person    schedule
comment
Похоже, это не работает, поскольку изменение свойства pk, похоже, не изменяет фактическое поле первичного ключа (в моем случае «id»). Таким образом, ModelForm по-прежнему перезаписывает существующий объект, а не создает новый. - person oogles; 01.09.2010
comment
Я считаю, что вам нужно сохранить модель после установки pk в None и перед переходом в форму. Я просто обрабатываю это в представлении, поэтому прямо перед сохранением формы вы хотите сделать этот обмен (form.instance.pk = None; form.instance.save()) - person natehawkboss; 07.06.2021