2012-12-03 48 views
0

沒有什麼比不理解爲什麼有效。幾天前我問了這個問題,並找出了一個修復方法,但我不知道它爲什麼有效:爲什麼我的django formset需要指針字段引用?

How to debug a Django MultiValueDictKeyError on Formset POST

爲什麼formset需要指向formset模型表單模型超類的指針字段引用?我有其他的表單就像這樣,沒有。

爲了使這個獨立的問題,下面是詳細信息:

當我發表我的表單集,我得到一個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']}>" 

的關鍵部分是,Django是尋找後數據的密鑰documents-0-attachment_ptr。這很令人困惑 - 一個Document是Attachment的子類。所有其他的帖子數據如預期。爲什麼Django需要我的formset中的指針數據?

這裏是該formset使用的形式:

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') 

附加信息:

奇怪的是,的的inital後formset工作正常。只有在更新文章中 - 當formset中有初始表單時 - 當我收到此錯誤時。當我嘗試從formset中刪除表單時也會發生這種情況。

另外,formset是一個使用django香脆形式的通用內聯formset。

更新

有對所使用的模板代碼的請求。下面是簡化版本:

{% 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> 

我加入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的要求您提供一個指向超類中使用一個子類的模型一切形式的?這讓我感到驚訝。

回答

1

不要忘記,非抽象模型的子類實際上只是兩個模型之間的一對一關係。所以很自然Django需要某種形式的從一個到另一個的指針,否則它不可能知道子表更改時父表中的哪一行要更新。

+0

而且,由於我的其他案例是抽象模型的子類,因此您的答案解釋了我所看到的內容。謝謝!這不是一個問題,因爲我現在必須包含在表單中的_ptr字段可以被惡意帖子改變嗎? – Erik

相關問題