Django将函数视图为formset_factory表单

时间:2013-02-08 07:43:33

标签: django forms

我正在尝试使用单个视图功能,该功能将显示一个空的表单,并且还会显示以前填充的表单以供进一步编辑。这是我目前的观点:

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模板。

1 个答案:

答案 0 :(得分:1)

我不会使用modelformset来做你所建议的事情。只需在同一视图中使用两个表单,添加prefix即可区分它们 -

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>

查看customizing the form template上的文档以获取更多信息。