我正在尝试使用单个视图功能,该功能将显示一个空的表单,并且还会显示以前填充的表单以供进一步编辑。这是我目前的观点:
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模板。
答案 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_form
和existing_form
。在模板中输出这些表单的最简单方法是 -
<form action="/contact/" method="post">
{{ existing_form.as_p }}
{{ new_form.as_p }}
<input type="submit" value="Submit" />
</form>
查看customizing the form template上的文档以获取更多信息。