【问题标题】:Django modelformsets contain no POST dataDjango modelformsets 不包含 POST 数据
【发布时间】:2022-10-24 02:09:05
【问题描述】:

我有以下型号

模型.py

class Activity(Model):
    user = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
    activity = CharField(max_length=100, default='')
    number = IntegerField(default=1)

和以下模型形式

表格.py

class ActivityForm(ModelForm):
    class Meta:
        model = Activity
        fields = ['activity']

在视图中做成modelformset

视图.py

activities = Activity.objects.filter(user=request.user)
ActivityFormSet = modelformset_factory(Activity, form=ActivityForm)
formset = ActivityFormSet(queryset=activities)
if request.method == 'POST':
    if 'save' in request.POST:
        formset = ActivityFormSet(request.POST)
        if formset.is_valid():

我的观点到此为止。因为表单集无效,并且 formset.errors 给了我:

[{'activity': ['This field is required.'], 'id': ['This field is required.']}, {}] 

从我的模板:

<form enctype="multipart/form-data" method = "POST">
    {% csrf_token %}
    {{ formset.management_form }}
                {% for hidden in formset.hidden_fields %}
                    {{ hidden }}
                {% endfor %}
    {% for activity in activities %} 
         <div class="expandable-input-small" id="input_activity{{ activity.number }}" contenteditable="true"></div>
<div id="form_activity{{ activity.number }}">{% for hidden in formset.form.hidden_fields %}{{ hidden }}{% endfor %}{{ formset.form.activity.as_hidden }}</div>
{% endfor %}
<button name="save" class="btn btn-primary" type = "submit" value = "Click" onclick="get_data()">Save</button>
</form>

在使用函数 get_data() 提交之前,我使用 javascript 将数据从 contenteditable 传输到隐藏的表单集表单字段。我已经测试并确认该函数通过在表单外调用它并将输入字段设置为不隐藏来工作。

无论我做什么 - 即使我取消隐藏字段并手动输入数据,表单集似乎也不包含任何发布数据。我尝试使用文档来理解这一点 - 但大多数示例(出于某种原因)取自控制台命令,而不是在模板中显示表单集。

我究竟做错了什么?我该如何解决?

【问题讨论】:

    标签: django django-models django-forms django-templates


    【解决方案1】:

    有了这条线

     {% for activity in activities %} 
    

    您正在循环执行活动。但是,您不是在表单集中的表单中循环。所以,

    {{ formset.form.activity.as_hidden }}
    

    每次都创建相同的字段,导致 POST 中缺少字段

    尝试类似的东西

    <form enctype="multipart/form-data" method = "POST">
        {% csrf_token %}
        {{ formset.management_form }}
        {% for activity in activities %} 
            <div class="expandable-input-small" id="input_activity{{ activity.number }}" contenteditable="true">
            </div>
            <div id="form_activity{{ activity.number }}">
            {% for form in formset %}
                {% if forloop.counter == forloop.parentloop.counter %}
                     {{ form.activity.as_hidden }}
                     {{ form.id.as_hidden}}
                {%endif%}
            {% endfor %}
            </div>
        {% endfor %}
        <button name="save" class="btn btn-primary" type = "submit" value = "Click" onclick="get_data()">Save</button>
    </form>
    

    这应该为您提供每个活动所需的字段(通过计数与活动循环匹配表单集循环)。通常,对于 formset 表单,隐藏 ID 是自动提供的,但在这里,希望显式创建它 as_hidden 将完成这项工作。

    【讨论】:

    • 这主要有效 - 现在验证了表单内容,但没有验证 ID,错误 {'id': ['Select a valid choice.该选项不是可用选项之一。']}。尝试尝试查看 POST 数据中是否缺少错误(意味着问题出在模板中),或者是否无法从 POST 数据中识别(视图中的问题 - 但我认为模型表单自动解决了这个问题)
    • form.id.as_hidden,例如name = 'form_0_id',应该有一个与activity.id 相同的值——这就是formset 如何知道表单是针对哪个Activity 的。您可以在模板中输出两者以确保它们匹配。如果他们不这样做,请告诉我。
    • 值是相同的 - 但我仍然收到错误。我认为这意味着错误在视图中?
    • 我还看到您同时使用了 form2(用于 management.form 数据)和 formset。 management.form 是否应该用于表单集?
    • 啊,是的 - 实际上这是这个问题的一个错字(现在更正了)。 form2 是我在模板/视图中使用的实际命名约定,我将其更改为 formset 以使问题易于理解。
    猜你喜欢
    • 1970-01-01
    • 2014-05-16
    • 2019-02-20
    • 2022-01-15
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    相关资源
    最近更新 更多