【问题标题】:Django Model Form Set POSTs But Does Not SaveDjango 模型表单设置 POST 但不保存
【发布时间】:2018-05-14 16:24:03
【问题描述】:

我有一个基于模型表单集 (forms.py) 的 Django 站点。我的观点(views.py)选择了模型表单集。该视图在我的模板 (alerts.html) 中呈现。用户会看到填充了实体和逻辑的警报列表。他们必须在表单集中的一个或多个表单上输入评论,然后单击提交按钮将一个或多个表单发布到数据库。当前单击提交按钮时,页面刷新并在runserver中显示成功的POST(200),但数据未保存到DB。 formset.errors 表明每个字段都需要comment,而不仅仅是更改的表单。

我尝试在调用formset.save() 之前添加if formset.has_changed():,但问题仍然存在。

我应该如何更改我的项目以允许正确保存模型表单集?

编辑:我迁移blank=True 以征求意见。现在,当单击提交按钮时,数据将被保存。但是,注释文本(以及表单的其余部分)仍保留在模板的表格中。再次点击提交时,评论文本仍然存在,entitylogic 被替换为空白。

forms.py

class AlertForm(ModelForm):
    class Meta:
        model = Alert
        fields = [
            'comment'
        ]

AlertFormSet = modelformset_factory(Alert, extra=0, form=AlertForm)

views.py

def alerts(request):
    newAlerts = Alert.objects.filter(comment='')
    formset = AlertFormSet(request.POST or None, queryset=newAlerts)
    context = {'formset':formset}
    if request.method == 'POST':
        formset = formset
        if formset.is_valid():
            formset.save()
    else:
        formset = formset
    print(formset.errors)
    return render(request, 'alerts/alerts.html', context)

alerts.html

<form method='POST' action=''>
  {{ formset.management_form }}
  {% csrf_token %}
  <input name="submit" value="Submit" id="submit-id-submit" type="submit">
  {% for form in formset %}
     {% for hidden_field in form.hidden_fields %}
       {{ hidden_field }}
     {% endfor %}
  {% endfor %}
  <table>
    <thead>
      <tr>
        <th>Entity</th>
        <th>Logic</th>
        <th>Comment</th>
      </tr>
     </thead>
     <tbody>
     {% for form in formset %}
     <tr>
        <td>{{ form.instance.entity }}</td>
        <td>{{ form.instance.logic }}</td>
        <td>{{ form.comment }}</td>
     </tr>
     {% endfor %}
     </tbody>
    </table>
 </form>

【问题讨论】:

  • 我编辑了我的答案希望它可以帮助你解决问题
  • @ZachB。谢谢您的帮助!但是,我之前已经走上了循环表单的道路,我真的很想坚持提交整个表单集。我知道这是可能的(我从那里得到视图代码):docs.djangoproject.com/en/1.11/topics/forms/modelforms/…
  • 您希望entitylogic 可编辑吗?您似乎没有在模板中包含这些字段。您没有在模板中包含任何错误——它们会提示问题所在。如果您循环通过{% for form in formset %} 而不是{% for field in formset %},则不会那么混乱。
  • 不,只有评论需要可编辑。我会将 field 更改为 form 以减少混乱 - 谢谢!我正在使用field.instance.entityfield.instance.logic,因为它们是外键字段,我希望看到相关的文本而不是随机的 id 数字
  • 您已将循环更改为{% for form in formset %},但您仍然在循环内使用field,例如{{ field.instance.entity }}

标签: python django django-forms django-templates django-views


【解决方案1】:

表单集无效,因为您没有提交 entitylogic 字段的值。如果您在视图中打印formset.errorsincluded the form errors in the template,您会看到这一点。

由于您不希望 entitylogic 可编辑,因此您不应将它们包含在表单集的字段中:

class AlertForm(ModelForm):
    class Meta:
        model = Alert
        fields = [
            'comment',
        ]

由于您在表单中定义了fields,因此您在调用modelformset_factory 时不需要包含exclude

AlertFormSet = modelformset_factory(Alert, extra=0, form=AlertForm)

【讨论】:

  • 谢谢 - 如果表单集中只有一个表单,但有多个表单,这肯定会起作用。我认为关键是用户可以为一个或多个表单输入评论,并且他们应该可以随时提交。所以现在表单集中有 10 个表单,呈现为内联表。如果用户为一个表单输入评论并点击提交,formset.errors 表明其他九个表单需要comment
  • 然后将注释设为可选字段(例如,在模型字段上设置 blank=True)。
  • 我进行了这些迁移,现在正在保存数据......但是,重定向后评论文本和表单仍保留在表格中。当第二次单击提交按钮时(在初始保存之后),注释文本仍然存在,实体和逻辑变为空白。 formset.errors 显示[{}, {}, {} ..... {}]
  • 我无法解释这种行为。推荐的方法是在成功发布请求后重定向。
【解决方案2】:

尝试像这样遍历表单集中的数据

if request.method == 'POST':
    formset = formset
    if formset.is_valid():
        for form in formset:
            cleaned_data = form.cleaned_data
            entity = cleaned_data.get('entity')
            logic = cleaned_data.get('logic')
            comment = cleaned_data.get('comment')
            # create a new Alert object here
            alert = Alert(entity=entity, logic=logic, comment=comment)
            alert.save()

【讨论】:

  • 这不起作用 - 将 method="post" 添加到我的按钮,并且存在同样的挑战
  • 哎呀,我错了,它应该在
    标记中,它已经是,对不起:P
  • 您的控制台日志是否显示了对服务器的 POST 请求?只是不保存?
  • 是的,开发服务器显示成功的 POST 请求 (200),但表单(或多个表单,如果填写了多个)没有保存到数据库中
猜你喜欢
  • 2021-01-27
  • 2023-01-23
  • 2011-01-08
  • 1970-01-01
  • 2020-12-03
  • 2018-11-23
  • 2021-02-15
  • 2013-04-12
  • 1970-01-01
相关资源
最近更新 更多