问题
I havent posted a question here before, read mostly.
Im learning Django and got file upload working before . But now i've broke it somehow.
request.FILES is empty when im uploading but i can see the filename in request.raw_post_data.
here is the code for the html
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Upload Photo" />
</form
the form
class PhotoUploadForm(forms.Form): title = forms.CharField(max_length=50) description = forms.CharField(required=False,max_length="254") photo = forms.ImageField()
the view
class PhotoUploadView(FormView):
template_name ="album/photo_upload.html"
form_class = PhotoUploadForm
def get_context_data(self,**kwargs):
context = super(PhotoUploadView,self).get_context_data(**kwargs)
context['user_info'] = self.request.user
if 'upload_form' in kwargs:
context['upload_form'] = kwargs['upload_form']
else:
context['upload_form'] = PhotoUploadForm()
album = get_object_or_404(Album,id=self.kwargs['album_id'])
context['album'] = album
context['form'] = self.form_class
return context
def post(self,*args,**kwargs):
print self.request.FILES
print self.request.raw_post_data
if self.request.method == "POST":
form = PhotoUploadForm(self.request.POST,self.request.FILES)
if form.is_valid():
photo = Photo()
photo.title = form.cleaned_data['title']
photo.summary = form.cleaned_data['description']
photo.album = get_object_or_404(Album,id = kwargs['album_id'])
photo.is_cover_photo = True
path = self.generate_filename(self.request.FILES['photo'].name,self.request.user,kwargs['album_id'])
destination = open(path,"wb+")
for chunk in self.request.FILES['photo'].chunks():
destination.write(chunk)
destination.close()
photo.imagePath = path
photo.save()
return self.render_to_response(self.get_context_data(upload_form=form)
回答1:
It would be much easier to do what you're trying to do using ModelForms:
#forms.py
class PhotoAddForm(forms.ModelForm):
class Meta:
model = Photo
def __init__(self, album_id, *args, **kwargs):
self.album_id = album_id
super(PhotoAddForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
photo = super(PhotoAddForm, self).save(commit=False)
photo.album_id = self.album_id
if commit:
photo.save()
return photo
#views.py
class AddPhotoView(CreateView):
form_class = PhotoAddForm
template_name = 'photos/add_photo.html'
def get_success_url(self):
return reverse('photo_add_successful')
def get_form_kwargs(self):
kwargs = super(AddPhotoView, self).get_form_kwargs()
kwargs.update({
'album_id': self.kwargs['album_id'],
})
return kwargs
回答2:
I did it using FormView too (I was mainly learning how to use it, django doc for the latest generic class views is pretty limited); while @bezidejni answer might be a better solution, this is how you get it working wrt your question:
class PhotoUploadView(FormView):
template_name ="album/photo_upload.html"
form_class = PhotoUploadForm
def form_valid(self, form):
"""
This is what's called when the form is valid.
"""
photo = form.cleaned_data['photo'] # <= this is your uploaded file in memory
# read your photo object by chunks, save it to disk, or whatever else
# ....
# then keep on going! you can make the 'get_success_url' more complex should you need to.
return HttpResponseRedirect(self.get_success_url())
PS.
you shouldn't use render_to_response if you are using FormView; overload get_context_data
if you need to pass context to the template that is already specified as template_name
来源:https://stackoverflow.com/questions/7288528/django-form-upload-request-files-empty