【问题标题】:Django ModelForm does not validate image file uploadDjango ModelForm 不验证图像文件上传
【发布时间】:2016-03-02 05:30:23
【问题描述】:

我有一个带有一个图像字段的 ModelForm,如下所示:

class ProfilePhotoForm(ModelForm):
    class Meta:
        model = ProfilePhoto
        fields = ["image"]

我有一个使用 ModelForm 的视图,如下所示:

class ProfileView(View):

    def get(self, request):
        user = User.objects.first()
        profile = Profile.objects.get(user=user)
        photo_form = ProfilePhotoForm(instance=profile)
        profile_form = ProfileForm(instance=profile)
        return render(request, "edit_profile.html", {"photo_form": photo_form, "profile_form": profile_form })

    def post(self, request):    
        if 'picture' in self.request.POST:
            photo_form = ProfilePhotoForm(request.POST, request.FILES, prefix='photo_form')
            import ipdb; ipdb.set_trace()
            if photo_form.is_valid():
                image = photo_form.cleaned_data['image']
                user = User.objects.first()
                profile = Profile.objects.get(user=user)
                profile_photo = ProfilePhoto.objects.get(profile=profile)
                if profile_photo:
                    profile_photo.delete()
                ProfilePhoto.objects.create(profile=profile, image=image)
        elif 'profile' in self.request.POST:
            profile_form = ProfileForm(request.POST, prefix='profile_form')
            if profile_form.is_valid():
                profile_form.save()
        return render(request, "edit_profile.html", {})

视图的GET请求渲染的模板如下:

<div class="wrapper">   
    <form method="POST" enctype="multipart/form-data" action="">
        <input type="hidden" name="csrfmiddlewaretoken" value="5sY3rFOqYjJTAkOUKVcoAkIthA10RbCc">
        <input class="form-control margin10" id="id_image" name="image" placeholder="Image" type="file">
        <input class="btn btn-default btn-block btn-primary margin10" id="register" type="submit" name="picture" value="Upload Profile Picture">
    </form>
    <form method="POST" action="">
        <input type="hidden" name="csrfmiddlewaretoken" value="5sY3rFOqYjJTAkOUKVcoAkIthA10RbCc">
        <input class="form-control margin10" id="id_display_name" maxlength="50" name="display_name" placeholder="Display name" type="text" value="Kent Shikama">
        <textarea class="form-control margin10" cols="40" id="id_description" name="description" placeholder="Description" rows="10">A CS major taking CS133</textarea>
        <input class="btn btn-default btn-block btn-primary margin10" id="register" type="submit" name="profile" value="Change Profile">
    </form>
</div>

在 ProfileView 类中,我放置了一个 ipdb 调试停止。以下是一些可能相关的输出:

ipdb> photo_form.data
<QueryDict: {'picture': ['Upload Profile Picture'], 'csrfmiddlewaretoken': ['5sY3rFOqYjJTAkOUKVdoAkIthA10RbCc']}>
ipdb> photo_form.files
<MultiValueDict: {'image': [<InMemoryUploadedFile: self_square.jpg (image/jpeg)>]}>
ipdb> photo_form.errors
{'image': ['This field is required.']}

我搜索了很多相关的问题:他们中的大多数都说要仔细检查 request.FILES 是否已传递到表单中并且设置了 enctype。 photo_form.files 返回 InMemoryUploadedFile 的事实似乎表明图像确实已上传。因此,我对为什么表单没有验证感到困惑。有人知道为什么吗?

【问题讨论】:

    标签: django forms file-upload


    【解决方案1】:

    问题是与前缀“photo_form-image”组合的名称与“image”的 HTML 输入名称不匹配

    我在浏览 ipdb 时发现了这一点:

    ipdb> l
        335 
    --> 336     def value_from_datadict(self, data, files, name):
        337         "File widgets take data from FILES, not POST"
        338         return files.get(name, None)
        339 
    ipdb> name
    'photo_form-image'
    ipdb> files.get(name)
    ipdb> files.get('image')
    <InMemoryUploadedFile: self_square.jpg (image/jpeg)>
    

    【讨论】:

      猜你喜欢
      • 2013-08-22
      • 2012-09-30
      • 2013-06-24
      • 2017-03-06
      • 2014-01-23
      • 2013-11-26
      • 2011-01-09
      • 2018-11-03
      相关资源
      最近更新 更多