Рассмотрим модель:Каков правильный способ создания Django ModelForm в представлении создания/редактирования?
class MyModel(models.Model):
token = models.CharField(unique=True, db_index=True, max_length...)
name = models.CharField(...)
...
(За исключением: цель маркера является, чтобы быть альтернативой отображения и с использованием идентификатора в URL-адресов, это не является первичным ключом.)
и его форма :
class MyForm(forms.ModelForm):
...
class Meta:
model = models.MyModel
fields = '__all__' # Django 1.6
И его шаблон:
...
<form action={% url 'create_or_edit_mymodel' %} ...>{% csrf_token %}
{{ form.token.as_hidden }}
<label for="id_name">Name:</label>
{{ form.name }}
...
И, окончательное ly, вид сверху:
def create_or_edit_mymodel(request, token=None):
# [A] Entering via a hyperlink with the token, editing existing model
if token:
m = models.MyModel.objects.filter(token=token).first()
form = forms.MyForm(instance=m)
# [B] Postback from form
elif request.POST:
form = forms.MyForm(request.POST)
# [C] Entering via a hyperlink without the token, creating new model
else:
m = create_new_mymodel(...) # somewhere else
form = forms.MyForm(instance=m)
if request.method == 'POST' and form.is_valid():
saved = form.save()
# Determine if 'Save' or 'Save & Close' was clicked... assume 'Save'...
form = forms.MyForm(instance=saved)
return shortcuts.render(request, '...', { 'form': form }, context_instance=RequestContext(request))
Это не работает. Проблема заключается в том, что идентификатор модели не представляется доступным для Django, поэтому ввод в представлении в [A] заполняет форму всем, как ожидалось, но нажатие «Сохранить» и вход в представление в [B] пытается сохранить модель без идентификатора, а уникальное ограничение на поле «токен» срабатывает.
Я попытался добавить поле идентификатора в виде:
{{ form.id.as_hidden }} # or...
{{ form.pk.as_hidden }}
Но ничего не визуализируется.
Этот вид выглядит довольно неудобным для меня, поэтому я надеюсь, что я сделаю это сложнее, чем это должно быть.
Где экземпляр приходит? Я просматриваю его снова, используя скрытое поле токена, как я это делаю в [A]? – Seth
@Seth из аргумента представления (токен). Ваша форма 'action' должна указывать на то же местоположение с тем же самым токеном – ndpu
Это больше не доступно в postback, но я могу вытащить его из request.POST. Я собираюсь отредактировать ваш ответ; надеюсь, вы не против. – Seth