在创建/编辑视图中构造Django ModelForm的正确方法是什么?

时间:2014-02-10 22:26:07

标签: python django django-forms

考虑一个模型:

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 }}

但没有任何东西被渲染。

这个观点对我来说看起来很不舒服,所以我希望我能让它变得比它需要的更难。

1 个答案:

答案 0 :(得分:2)

在这里,您应该同时传递request.POST 和实例以形成init:

# [B] Postback from form
elif request.POST: 
    form = forms.MyForm(request.POST, instance=instance)