2015-11-28 33 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)>