我的目标是在一个模板中使用两个模型。我试过各种方法来解决这个问题,但没有成功。最初我有两个视图,两个模型和两个表单。搜索之后,我发现有人在使用inlineformsets。所以我放弃了其中一个视图并设置了inlineformset。 这是目前我正在做的事情,而且似乎要碰壁了。在
模板呈现到浏览器,“object_list”部分显示所需的数据库内容,“form”部分呈现表单并正确验证/保存数据。问题出在“表单集”上。没有呈现任何字段(我希望看到一个下拉列表,因为该字段是一个外键),当按下“提交”按钮时,我得到:
AttributeError at /settings/
'NoneType' object has no attribute 'save'
如果您能帮助您找到错误或其他解决方案的建议,我们将不胜感激。在
class RevisionSettingsView(CreateView):
template_name = 'settings/revisionsettings_view.html'
model = RevisionSettings
form_class = SettingsForm
success_url = reverse_lazy('globalsettings')
success_message = 'Successfully added your new revision type'
def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SettingsFormSet(instance = RevisionSettings)
return self.render_to_response(
self.get_context_data(form=form,
formset=formset))
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SettingsFormSet(self.request.POST)
if 'rev_settings_form_1' in self.request.POST:
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
elif 'rev_settings_form_2' in self.request.POST:
if formset.is_valid():
return self.formset_valid(formset)
else:
return self.form_invalid(formset)
def form_valid(self, form):
self.object = form.save()
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def formset_valid(self, formset):
self.object.save()
formset.instance = self.object
formset.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, formset):
return self.render_to_response(self.get_context_data(form=form,formset=formset))
def get_context_data(self, **kwargs):
kwargs['object_list'] = RevisionSettings.objects.order_by('global_revision_type')
return super(RevisionSettingsView, self).get_context_data(**kwargs)
from django import forms
from django.forms.models import inlineformset_factory
from .models import RevisionSettings, RevisionDefaultType
class SettingsForm(forms.ModelForm):
class Meta:
model = RevisionSettings
class DefaultSettingsForm(forms.ModelForm):
class Meta:
model = RevisionDefaultType
SettingsFormSet = inlineformset_factory(RevisionSettings, RevisionDefaultType)
(我删除了大部分的HTML样式以保持信息的重点)
{% extends 'base_private.html' %}
{% block content %}
{% for object in object_list %}
<tr>
<td align="center">{{ object.global_revision_type }}</td>
<td align="center">{{ object.global_revision_description }}</td>
<td align="center"><a href="/settings/{{ object.id }}/delete" class="tooltip-test" title="" data-original-title="Delete selected revision type"><span class="glyphicon glyphicon-remove-circle"></span></a></td>
</tr>
{% endfor %}
<form action = '{{ action }}' method = 'POST' class="form-horizontal" role="form">
{% csrf_token %}
<tr>
<td align="center">
{{ formset.management_form }}
{% for form in formset %}
{{ form.id }}
{{ form.defaultrevisiontype.label_tag }}
{{ form.defaultrevisiontype }}
{% endfor %}
</td>
</tr>
<span class="input-group-addon">
<input type = 'submit' name = 'rev_settings_form_2' value = 'Update Default Revision Type' class = 'btn btn-success'>
</span>
<td align="center">{{ form.global_revision_type }}{{ form.global_revision_type.errors }}</td>
<td align="center">{{ form.global_revision_description }}{{ form.global_revision_description.errors }}</td>
</tr>
<span class="input-group-addon">
<input type = 'submit' name = 'rev_settings_form_1' value = 'Add Revision Type' class = 'btn btn-success'>
</span>
</form>
{% endblock %}
对于两个表单来说,表单集是多余的。这实际上并不难,但记录不充分。你可以使两个表单都是同一个表单类型,只需提供一个前缀。在
这些表单只是普通的Django表单,不需要特殊设置。您可以更改它们验证的顺序,并保存其中一个,即使另一个未验证(如果您选择的话)。在
在HTML模板中,将两个表单包装在同一个标记中,它们将同时提交。如果希望窗体转到不同的视图函数,请指定两个不同的元素。在
谢谢你的帮助。指针确实帮助我找到了这个解决方案。主要的变化是“def get”,如下所示。我把表格扔了,就这样递过去了。在
我不知道这是可能的!再次感谢。在
相关问题 更多 >
编程相关推荐