考虑一个模型:
class MyModel(models.Model):
token = models.CharField(unique=True, db_index=True, max_length...)
name = models.CharField(...)
...
(旁白:令牌的目的是替代在URL中显示和使用ID;它不是主键。)
其形式:
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 }}
...
最后,它的观点是:
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))
这不起作用。问题是模型的ID似乎不可用于Django,因此在[A]处输入视图会按预期填充表单,但单击“保存”并在[B]处输入视图会尝试保存没有ID的模型,以及'token'字段的唯一约束。
我尝试将id字段添加到表单中:
{{ form.id.as_hidden }} # or...
{{ form.pk.as_hidden }}
但没有任何东西被渲染。
这个观点对我来说看起来很不舒服,所以我希望我能让它变得比它需要的更难。
答案 0 :(得分:2)
在这里,您应该同时传递request.POST
和实例以形成init:
# [B] Postback from form
elif request.POST:
form = forms.MyForm(request.POST, instance=instance)