在Djang中在一个模板中显示两个表单

2024-06-25 23:39:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是在一个模板中使用两个模型。我试过各种方法来解决这个问题,但没有成功。最初我有两个视图,两个模型和两个表单。搜索之后,我发现有人在使用inlineformsets。所以我放弃了其中一个视图并设置了inlineformset。 这是目前我正在做的事情,而且似乎要碰壁了。在

模板呈现到浏览器,“object_list”部分显示所需的数据库内容,“form”部分呈现表单并正确验证/保存数据。问题出在“表单集”上。没有呈现任何字段(我希望看到一个下拉列表,因为该字段是一个外键),当按下“提交”按钮时,我得到:

AttributeError at /settings/

'NoneType' object has no attribute 'save'

如果您能帮助您找到错误或其他解决方案的建议,我们将不胜感激。在

代码:

在模型.py

^{pr2}$

在视图.py

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)

在表单.py

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

(我删除了大部分的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 %}

Tags: selfformgetreturnsettingsobjectdeftype
2条回答

对于两个表单来说,表单集是多余的。这实际上并不难,但记录不充分。你可以使两个表单都是同一个表单类型,只需提供一个前缀。在

def parent_apply(request):
  if request.method == 'POST':
    parent_form = SignupForm(request.POST, prefix="parent")
    student_form = StudentApplyForm(request.POST, prefix="student")
    if parent_form.is_valid() and student_form.is_valid():
      parent = parent_form.save()
      student = student_form.save(parent)
    else: messages.error(request, "Please correct the errors marked in red.")
  else:
    parent_form = SignupForm(prefix="parent")
    student_form = StudentApplyForm(prefix="student")

  return render_to_response('template_path/forms.html', { 'parent_form':parent_form, 'student_form':student_form }, context_instance=RequestContext(request))

这些表单只是普通的Django表单,不需要特殊设置。您可以更改它们验证的顺序,并保存其中一个,即使另一个未验证(如果您选择的话)。在

在HTML模板中,将两个表单包装在同一个标记中,它们将同时提交。如果希望窗体转到不同的视图函数,请指定两个不同的元素。在

谢谢你的帮助。指针确实帮助我找到了这个解决方案。主要的变化是“def get”,如下所示。我把表格扔了,就这样递过去了。在

def get(self, request, *args, **kwargs):
     form = self.settings_form_class
     formset = self.default_form_class

     return self.render_to_response(self.get_context_data(form = form, formset = formset))

我不知道这是可能的!再次感谢。在

相关问题 更多 >