17

フォームセットを投稿すると、MultiValueDictKeyErrorが発生します。具体的には:

MultiValueDictKeyError at /core/customers/1/update/documents/
"Key u'documents-0-attachment_ptr' not found in <QueryDict: {u'documents-1-last_modified_date': [u''], u'documents-1-name': [u''], u'documents-MAX_NUM_FORMS': [u''], u'documents-0-attachment_file': [u''], u'documents-INITIAL_FORMS': [u'1'], u'documents-1-document_type': [u''], u'documents-0-notes': [u''], u'documents-1-notes': [u''], u'submit': [u'Submit changes'], u'documents-0-DELETE': [u'on'], u'documents-1-attachment_file': [u''], u'documents-0-document_type': [u''], u'documents-TOTAL_FORMS': [u'2'], u'documents-0-name': [u'test'], u'documents-1-creation_date': [u''], u'documents-0-creation_date': [u'2012-12-01 23:41:48'], u'csrfmiddlewaretoken': [u'NCQ15jA7erX5dAbx20Scr3gWxgaTn3Iq', u'NCQ15jA7erX5dAbx20Scr3gWxgaTn3Iq', u'NCQ15jA7erX5dAbx20Scr3gWxgaTn3Iq'], u'documents-0-last_modified_date': [u'2012-12-01 23:41:48']}>"

documents-0-attachment_ptr重要な部分は、Djangoが投稿データでキーを探していることです。これは紛らわしいです-ドキュメントは添付ファイルのサブクラスです。他のすべての投稿データは期待どおりです。Djangoがフォームセットにポインターデータを必要とするのはなぜですか?

フォームセットで使用されるフォームは次のとおりです。

class DocumentInlineForm(forms.ModelForm):  # pylint: disable=R0924
    attachment_file = forms.FileField(widget=NoDirectoryClearableFileInput)
    notes = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={'rows': 2,}), 
    )
    helper = DocumentInlineFormHelper()

    class Meta: # pylint: disable=W0232,R0903
        fields = (
            'attachment_file', 
            'creation_date',
            'document_type',
            'last_modified_date',
            'name',
            'notes',
        )
        model = Document

そして、これがドキュメントモデルです。

"""
Handles document model definitions.
"""
from django.db import models
from eee_core.models.attachments import Attachment
from django.db.models.signals import pre_save
from datetime import datetime
from django.utils.timezone import utc

class Document(Attachment):
    """
    A document is an attachment with additional meta data.
    """
    creation_date = models.DateTimeField(
        blank=True, 
        null=True,
    )
    document_type = models.CharField(
        blank=True, 
        choices=(
            ('CONTRACT', 'Contract'),
            ('INVOICE', 'Invoice'),
            ('FACILITY', 'Facility change form'),
            ('LOA', 'Letter of authorization'),
            ('USAGE', 'Usage history document'),
            ('OTHER', 'Other'),
        ),
        default=None, 
        null=True, 
        max_length=8, 
    )
    last_modified_date = models.DateTimeField(
        blank=True, 
        null=True,
    )
    notes = models.TextField(
        blank=True,
        null=True,
    )

    class Meta(Attachment.Meta): # pylint: disable=W0232,R0903
        """
        Sets meta fields for model.
        """
        app_label = 'core'

    def __str__(self):
        return unicode(self).encode('utf-8')

    def __unicode__(self):
        return unicode(self.name)

def pre_save_callback(sender, instance, *args, **kwargs): # pylint: disable=W0613
    if not isinstance(instance, Document):
        return

    if not instance.creation_date:
        instance.creation_date = datetime.utcnow().replace(tzinfo=utc)

    instance.last_modified_date = datetime.utcnow().replace(tzinfo=utc)

pre_save.connect(pre_save_callback, dispatch_uid='document_pre_save')

追加情報:

不思議なことに、フォームセットの最初の投稿は正常に機能します。このエラーが発生したのは、更新投稿(フォームセットに初期フォームがある場合)のみです。フォームセットからフォームを削除しようとしたときにも発生します。

また、フォームセットは、djangoのクリスピーフォームを使用した一般的なインラインフォームセットです。

アップデート

使用したテンプレートコードのリクエストがありました。簡略化されたバージョンは次のとおりです。

{% load crispy_forms_tags %}
{% load url from future %}
<form action="" method="post" enctype="multipart/form-data">
    {{ formset.management_form }}
    {% for subform in formset.forms %}
      {{ subform.id }}
      {% crispy subform %}
    {% endfor %}
    <div class="btn-toolbar">
        <input class='btn btn-primary' type="submit" name="submit" value="Submit changes" />
    </div>
</form>
4

4 に答える 4

50

これはOPには当てはまりませんがMultiValueDictKeyError、テンプレートに非表示のフィールドの一部がない場合は、が発生します。{{form}}迅速で汚いのではなく、フィールドがテンプレートに1つずつリストされている場合に発生する可能性があります: {{form.field1}}、、{{form.field2}}必要な非表示フィールドを除外します。

それらを元に戻すには、(フォームセット内の各フォーム/フォームに対して)線に沿って何かを実行します。

{% for hidden in form.hidden_fields %}
    {{ hidden }}
{% endfor %}

また

{% for form in formset %}    
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}    
{% endfor %}
于 2014-03-18T17:13:11.037 に答える
4

私も使っています

{% for hidden in form.hidden_fields %}
    {{ hidden }}
{% endfor %}

このように

<div role="tabpanel" class="tab-pane active" id="email">
                {% csrf_token %}
                {{ eformset.management_form}}
                    <div class="panel panel-default">
                        <div class="panel-body">
                            <div id="addemail" class="btn btn-success">
                                <span class="glyphicon glyphicon-plus" > 
                                </span>
                            </div>
                            <p><br></p>
                            {% for f in eformset %}
                                {% for hidden in f.hidden_fields %}
                                    {{ hidden }}
                                {% endfor %}
                                <div class="item_email_set">
                                    <table class="table table-condensed table-bordered">
                                    <tr>
                                        {% for field in f.visible_fields %} <!---->
                                            <td>
                                                {{ field.label }}
                                            </td>
                                        {% endfor %}

                                        <td>
                                        </td>
                                    </tr>
                                    <tr>
                                        {% for field in f.visible_fields %}
                                            <td>
                                                {{field.errors.as_ul}}
                                                {{field}}
                                            </td>
                                        {% endfor %}    
                                        <td class="btncolumn">      
                                            <p style="">
                                                <a class="delete_email_set" href="#">
                                                    <div  class="btn btn-danger">
                                                        <span class="glyphicon glyphicon-remove" > 
                                                        </span>
                                                    </div>
                                                </a>
                                            </p>
                                        </td>
                                    </tr>   

                                </table>
                            </div>  
                        {% endfor %}
                    </div>
                </div>  
            </div>

そして私はMultiValueDictKeyErrorを解決します

于 2015-08-07T21:33:21.380 に答える
1

attachment_ptrフォームのフィールドリストに追加することで、このエラーを止めました。だからDocumentInlineForm今です:

class DocumentInlineForm(forms.ModelForm):  # pylint: disable=R0924
    attachment_file = forms.FileField(widget=NoDirectoryClearableFileInput)
    notes = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={'rows': 2,}), 
    )
    helper = DocumentInlineFormHelper()

    class Meta: # pylint: disable=W0232,R0903
        fields = (
            'attachment_ptr',
            'attachment_file', 
            'creation_date',
            'document_type',
            'last_modified_date',
            'name',
            'notes',
        )
        model = Document

たぶんそれは私が前に知らなかったものですが、Djangoはサブクラス化されたモデルを使用するすべての形式でスーパークラスへのポインターを提供することを要求しますか?これは私を驚かせます。

このポインターフィールドが必要な理由を知りたいので、ここでそれに対処するための質問を開きました:なぜ私のdjangoフォームセットにポインターフィールド参照が必要なのですか?

于 2012-12-03T01:36:23.263 に答える
0

これはOPの答えではありませんが、同じエラーが発生しました。{{ subform.id }}テンプレートを視覚的に見ることができず、古いコードを整理していたため、誤ってテンプレートから削除しました。HTMLには、次のようなものがあります。

<input name="note_set-0-id" value="34632" id="id_note_set-0-id" type="hidden">
于 2018-03-03T10:00:16.070 に答える