【问题标题】:I get error MultiValueDictKeyError if I dont upload all 3 filefields in my django form如果我没有在我的 django 表单中上传所有 3 个文件字段,我会收到错误 MultiValueDictKeyError
【发布时间】:2015-03-30 23:36:02
【问题描述】:

我有一个包含大约 10 个字段的表单,其中 3 个是文件字段。

当我创建新记录时,没问题。 当我更新所有字段时,没问题。 当我只更新 3 个文件字段而不更新其他字段时,没问题。 但是如果我在模板中将一个文件字段留空,我会得到 MultiValueDictKeyError。 这并不酷,因为我希望用户能够上传或更新他们喜欢的任何字段,无论是 1 或 3 还是所有字段。

我到处搜索,但在任何地方都找不到这个确切的问题。任何帮助将不胜感激。

请原谅我冗长的代码。我是初学者。 形式是这样的……

class DocumentForm(forms.Form):
price= forms.IntegerField(max_value=1000, min_value=1,
                          label='1. Set Price in $',
                          help_text='*')

docfile = forms.FileField(allow_empty_file= True,
    label='3 Upload file 1',
    help_text='*')

docfile1 = forms.FileField(allow_empty_file= True,
    label='2. Upload file2',
    help_text='*')

docfile2=forms.FileField(allow_empty_file= True,
    label='4. Upload a file ',
    help_text='*')

name= forms.CharField(widget=forms.TextInput,help_text='*')

description=forms.CharField(widget=forms.Textarea,help_text='*')

RADIO_CHOICES = (
    ('none', "No Category"),
    ('one', "Music"),
    ('two', "Movie"),
    ('three', "Tutorial "),
)
category=forms.ChoiceField(
    choices=RADIO_CHOICES,
    widget=forms.RadioSelect(),
    label ='7. Select a Category for your upload',
    required=False,
    initial=False,
    )

isover18s =  forms.BooleanField(
    label='8. Is over 18 content advised?', 
    required=False,
    initial=False
 )

模型是这样的......

class Document(models.Model):

docfile1 =models.FileField(blank=True,null=True,upload_to= 'MEDIA_ROOT/documents/%Y/%m/%d',)
docfile = models.FileField(blank=True,null=True,upload_to= 'MEDIA_ROOT/documents/%Y/%m/%d',)
docfile2 =models.FileField(blank=True, null=True,upload_to= 'MEDIA_ROOT/documents/%Y/%m/%d',)

category= models.CharField(max_length=100, null=False, blank=False)
usersname =models.CharField(max_length=100, null=False, blank=False)
name= models.CharField(max_length=100, null=False, blank=False)
description=models.CharField(max_length=300, null=False, blank=False)
isover18s =models.BooleanField(default=False, verbose_name = "Over 18 Content advised?")

price=models.IntegerField(verbose_name="Price is in Dollars MAX is $999")
dateUploaded=models.DateTimeField(auto_now_add=True, auto_now=False)
preview_views=models.IntegerField(verbose_name="Pre Views")
views=models.IntegerField(verbose_name="Views")

视图很啰嗦,因为另一个视图使用相同的表单用于不同的目的,我不好。反正就是这样……

def edit_preview(request, document_id):

    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        form.fields['docfile'].required = False
        form.fields['docfile1'].required = False
        form.fields['docfile2'].required = False
        form.fields['category'].required = False
        form.fields['price'].required = False
        form.fields['description'].required = False
        form.fields['name'].required = False

        if form.is_valid():

            newdoc = Document.objects.get(id=document_id)
            newdoc.usersname = request.user.username                

            newdoc = Document(docfile = request.FILES['docfile'])
            if newdoc.docfile:
                myfile=newdoc.docfile

            newdoc = Document(docfile1 = request.FILES['docfile1'])
            if newdoc.docfile1:
                myfile1=newdoc.docfile1

            newdoc = Document(docfile2 = request.FILES['docfile2'])
            if newdoc.docfile2:
                myfile2= newdoc.docfile2

            newdoc = Document.objects.get(id=document_id)
            newdoc.usersname = request.user.username

            if myfile:
               newdoc.docfile = myfile
            if myfile:
               newdoc.docfile1 = myfile1
            if myfile:
               newdoc.docfile2 = myfile2

            newdoc.price=request.POST.get('price','')
            newdoc.category= request.POST.get('category','')
            newdoc.isover18s =request.POST.get('isover18s','')
            newdoc.name =request.POST.get('name','')
            newdoc.description =request.POST.get('description','')

            form.clean_content()
            if myfile:
                newdoc.save(update_fields=['docfile'])
            if myfile1:   
                newdoc.save(update_fields=['docfile1'])
            if myfile2: 
                newdoc.save(update_fields=['docfile2'])
            if request.POST.get('price'):
                newdoc.save(update_fields=['price'])
            if request.POST.get('category'):
                newdoc.save(update_fields=['category'])
            if request.POST.get('isover18s'):
                newdoc.save(update_fields=['isover18s'])
            if request.POST.get('name'):
                newdoc.save(update_fields=['name'])
            if request.POST.get('description'):   
                newdoc.save(update_fields=['description'])

    document = Document.objects.get(id=document_id)
    form = DocumentForm() 
    return render_to_response(
        'edit_preview.html',
        {'document': document, 'form': form},
        context_instance=RequestContext(request)
    )

模板表单太大且太乱,我似乎无法正确粘贴。希望有人可以提供帮助。

感谢一百万@knbk 这就是我将视图更改为的内容,它现在可以 100% 工作...

def edit_preview(request, document_id):

    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        form.fields['docfile'].required = False
        form.fields['docfile1'].required = False
        form.fields['docfile2'].required = False
        form.fields['category'].required = False
        form.fields['price'].required = False
        form.fields['description'].required = False
        form.fields['name'].required = False

        if form.is_valid():

            newdoc = Document.objects.get(id=document_id)
            newdoc.usersname = request.user.username                


            if request.FILES.get('docfile'):
                myfile=request.FILES.get('docfile')
            else:
                myfile=None

            if request.FILES.get('docfile1'):
                myfile1=request.FILES.get('docfile1')
            else:
                myfile1=None

            if request.FILES.get('docfile2'):
                myfile2=request.FILES.get('docfile2')
            else:
                myfile2=None

            if myfile:
               newdoc.docfile = myfile
            if myfile1:
               newdoc.docfile1 = myfile1
            if myfile2:
               newdoc.docfile2 = myfile2


            newdoc.price=request.POST.get('price','')
            newdoc.category= request.POST.get('category','')
            newdoc.isover18s =request.POST.get('isover18s','')
            newdoc.name =request.POST.get('name','')
            newdoc.description =request.POST.get('description','')

            form.clean_content()
            if myfile:
                newdoc.save(update_fields=['docfile'])
            if myfile1:   
                newdoc.save(update_fields=['docfile1'])
            if myfile2: 
                newdoc.save(update_fields=['docfile2'])
            if request.POST.get('price'):
                newdoc.save(update_fields=['price'])
            if request.POST.get('category'):
                newdoc.save(update_fields=['category'])
            if request.POST.get('isover18s'):
                newdoc.save(update_fields=['isover18s'])
            if request.POST.get('name'):
                newdoc.save(update_fields=['name'])

            if request.POST.get('description'):   
                newdoc.save(update_fields=['description'])

            p =request.POST.get('docfile')


    document = Document.objects.get(id=document_id)
    form = DocumentForm() 
    return render_to_response(
        'edit_preview.html',
        {'document': document, 'form': form},
        context_instance=RequestContext(request)
    )

【问题讨论】:

    标签: django forms filefield


    【解决方案1】:
    newdoc = Document(docfile = request.FILES['docfile'])
    ...
    
    newdoc = Document(docfile1 = request.FILES['docfile1'])
    ...
    
    newdoc = Document(docfile2 = request.FILES['docfile2'])
    

    如果密钥不存在,这将引发MultiValueDictKeyError。使用带有默认值的request.FILES.get()

    【讨论】:

    • 你的意思是这样吗...newdoc =request.FILES.get('docfile')
    • 是的,完全正确。 MultiValueDictrequest.FILES 是)实现了dict 拥有的所有方法。
    • 太棒了。那行得通,但现在我得到 nMemoryUploadedFile' 对象对于'if newdoc.docfile:' 行没有属性'docfile' 那么我如何检查是否有文件上传?非常感谢您的帮助
    • 感谢一百万 @knbk。如果可以的话,我会支持你:) 这就是我放在最后的内容,如果 request.FILES.get('docfile'): myfile=request.FILES.get('docfile') else: myfile 现在一切正常=无
    • 您可以将其缩短为myfile = request.FILES.get('docfile', None),如果该键不存在,则值为None
    猜你喜欢
    • 1970-01-01
    • 2018-07-09
    • 2021-07-27
    • 2014-12-26
    • 2012-07-06
    • 1970-01-01
    • 2011-08-19
    相关资源
    最近更新 更多