获取和发布 Django 表单集时的问题

Issues when getting and posting Django formset

我在项目中使用从模型派生的 Django 表单集时遇到两个问题:

  1. 获取。没有 required 个字段。我的模板不会将 required 添加到 <input> 标签,即使模型字段是非可选的——例如下面我的 QualificationDocument 模型中的 file 字段。我希望在其表单字段中看到 required,但没有。

    <input type="file" name="documents-0-file" id="id_documents-0-file">

如果没有这些 required 标记,则无法在客户端进行验证。

  1. POST。服务器端出现奇怪的验证错误。 当我提交此表单集时,它以错误告终。这是我在处理 request.POST:

    的视图函数中得到的

    formset.errors = [{'file': ['This field is required.']}]

如您所见,request.POST 中有该字段的数据,但我仍然收到错误消息:

request.POST =  <QueryDict: {'csrfmiddlewaretoken': ['asfdasdfasdfasdfQ8pasdafasdf5x33LRmpa7FdY4vKobTtwkWlEOIw3'], 'documents-TOTAL_FORMS': ['1'], 'documents-INITIAL_FORMS': ['0'], 'documents-MIN_NUM_FORMS': ['0'], 'documents-MAX_NUM_FORMS': ['1000'], 'documents-0-id': [''], 'documents-0-file': ['testpic.jpg'], 'documents-0-name': ['Test name'], 'documents-0-description': ['Test description']}>

下面是我models.py中的相关模型:

class Qualification(Data):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    amount_approved = models.PositiveIntegerField(blank=True, null=True)
    expiration_date = models.DateField(blank=True, null=True)

class QualificationDocument(models.Model):
    qualification = models.ForeignKey(Qualification, on_delete=models.CASCADE, related_name='documents')
    file = models.FileField(upload_to='qualification_docs/%Y/%m')
    name = models.CharField(max_length=128)
    description = models.CharField(max_length=256, blank=True, null=True)
    upload_date = models.DateTimeField(auto_now_add=True)

这是我的 views.py:

    q = Qualification.objects.get(id=q_id)
    QualificationDocumentFormSet = forms.inlineformset_factory(Qualification, QualificationDocument,
        fields=('file', 'name', 'description'),
        widgets={
            'name': forms.TextInput(attrs={'placeholder': 'Name'}),
            'description': forms.TextInput(attrs={'placeholder': 'Description'}) },
        extra=1)
    if request.POST:
        formset = QualificationDocumentFormSet(request.POST, instance=q)
        if formset.is_valid():
            formset.save()
    else:
        formset = QualificationDocumentFormSet(instance=q)
    # Render formset in Django template here

这是来自模板文件:

<form id='upload-form-{{ q.id }}' method="post" action="{% url 'submit_and_refresh' %}">
    {% csrf_token %}
    {{ formset.management_form }}
    <div id="form_set">
        {% for f in formset.forms %}
            {{ f.non_field_errors }}
            {{ f.errors }}
            <div class="doc-form">
                <div class="new-qual-doc-params">
                    {{ f.id }}
                    {{ f.file }}
                    {{ f.name }}
                    {{ f.description }}
                </div>
                <div class="new-qual-doc-delete">
                    {{ f.DELETE }}
                </div>
            </div>
        {% endfor %}
    </div>

    <button type="submit" class="btn btn-block">Save</button>
</form>

总而言之,我希望我的表单集的表单能够在客户端进行验证——为此我需要表单字段中缺少的 required 标记——并且提交能够正常工作.我做错了什么?

这不是完整的解决方案,但我错过了一些关键的事情:

  1. 表单上的加密类型。

    <form id='upload-form-{{ q.id }}' method="post" action="{% url 'submit_and_refresh' %}" enctype="multipart/form-data">

  2. 在表单集处理中包含 request.FILES。

    formset = QualificationDocumentFormSet(request.POST, request.FILES, instance=q)

这解决了问题 2。当我合并 jquery.formset.js 来处理从表单集中添加和删除表单时,问题 1 不再是问题。