1

我正在尝试一个单一的视图功能,它将显示一个空表单,并且还将显示一个先前填写的表单以供进一步编辑。这是我目前的看法:

def manage_contacts(request):
    ContactsFormSet = modelformset_factory(Contact)
    if request.method == 'POST':
        formset = ContactsFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect('/people/')
    else:
        formset = ContactsFormSet(queryset=Contact.objects.none())
    return render_to_response("contact.html", {
        "formset": formset,
    })

def edit_form(request, item_id):
    ContactsFormSet = modelformset_factory(Contact)
    if request.method == 'POST':
        instance = get_object_or_None(ContactsFormSet, pk=item_id)
        formset = Contact(request.POST, instance=instance)
        return render_to_response("contact.html", {
            "formset": formset,
    })

目前我有两个功能:第一个显示新表单,第二个用于编辑现有数据。第二个函数给出错误。我无法modelformset_factory从现有数据库列中获取显示数据。但是,第一个功能有效。我面临的障碍是我找不到将两者重写为单一视图函数的方法。这就是我在模型中所拥有的:https ://stackoverflow.com/a/14724113/498309

#urls.py
url(r'^edit/(?P<item_id>\d+)/$', 'app.views.edit_form'),

更新 1

def contact_view(request, item_id=None):
    context_data = {}
    if item_id:
        contact = get_object_or_404(Contact, pk=item_id)
    if request.method == 'POST':
        forms_are_valid = True
        new_form = ContactForm(request.POST, prefix='new')
        if new_form.is_valid():
            new_form.save()
        else:
            forms_are_valid = False
            context_data['new_form'] = new_form
        if item_id:
            existing_form = ContactForm(request.POST, instance=contact,
                prefix='existing')
            if existing_form.is_valid():
                existing_form.save()
            else:
                forms_are_valid = False
                context_data['existing_form'] = existing_form 
        if forms_are_valid: 
            return HttpResponseRedirect('thanks/')
    else: 
        new_form = ContactForm(prefix='new')
        context_data['new_form'] = new_form
        if item_id:
            existing_form = ContactForm(instance=contact, prefix='existing')
            context_data['existing_form'] = existing_form
    return render_to_response('contact.html', context_data)

此视图不显示表单。但它没有显示任何错误,它只显示 html 模板。

4

1 回答 1

1

我不会使用模型集来执行您的建议。只需在同一视图中使用两种形式,添加前缀以区分它们 -

from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response

def contact_view(request, contact_id=None):
    context_data = {}
    if contact_id:
        contact = get_object_or_404(pk=contact_id)
    if request.method = 'POST': 
        forms_are_valid = True
        new_form = ContactForm(request.POST, prefix='new')
        if new_form.is_valid():
            new_form.save()
        else:
            forms_are_valid = False
            context_data['new_form'] = new_form  errors
        if contact_id:
            existing_form = ContactForm(request.POST, instance=contact,
                                        prefix='existing')
            if existing_form.is_valid():
                existing_form.save()
            else:
                forms_are_valid = False
                context_data['existing_form'] = existing_form 
        if forms_are_valid: 
            return HttpResponseRedirect('thanks/')
    else: 
        new_form = ContactForm(prefix='new')
        context_data['new_form'] = new_form
        if contact_id:
            existing_form = ContactForm(instance=contact, prefix='existing')
            context_data['existing_form'] = existing_form
    return render_to_response('contact.html', context_data)

定义中的contact_id 参数允许您将视图用于新联系人和现有联系人。让两个 url 指向同一个视图,一个包含 contact_id,一个不包含 -

url(r'^contact/(?P<contact_id>\d+)/$', 'app.views.contact_view'),
url(r'^contact/$', 'app.views.contact_view'),

视图检查是否传递了 item_id - 如果是,那么我们知道我们正在处理现有的联系人。

恐怕我还没有真正运行过这段代码(而且它比我预期的要长一点),所以它可能有问题,但是我以前多次使用过这种模式——它确实有效。

更新

该视图将两个表单传递给模板new_formexisting_form. 在模板中输出这些表单的最简单方法是 -

<form action="/contact/" method="post">
    {{ existing_form.as_p }}
    {{ new_form.as_p }}
    <input type="submit" value="Submit" />
</form>

查看有关自定义表单模板的文档以获取更多信息。

于 2013-02-08T10:28:39.723 回答