2015-11-28 36 views
1

我有一个像场上的ModelForm如下:的Django的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类中,我放置了一个ip db调试停止。下面是一些潜在的相关输出:

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已穿入的形式,并且加密类型设置。 photo_form.files返回InMemoryUploadedFile的事实似乎表示图像确实已上传。因此,我很困惑为什么表单不能验证。任何人有任何想法为什么?

回答

0

的问题是,这个名字的前缀“photo_form形象”结合不匹配“形象”的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)>