我可以将我的文件保存到我告诉它的磁盘,但无法将其保存到实例中,我一点也不知道为什么!
class Song(models.Model):
name = models.CharField(max_length=50)
audio_file = models.FileField(upload_to='uploaded/music/', blank=True)
def create_song(request, band_id):
if request.method == 'POST':
band = Band.objects.get(id=band_id)
form = SongForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['audio_file'])
form.save()
return HttpResponseRedirect(band.get_absolute_url)
else:
form = SongForm(initial={'band': band_id})
return render_to_response('shows/song_upload.html', {'form': form}, context_instance=RequestContext(request))
def handle_uploaded_file(f):
ext = os.path.splitext(f.name)[1]
destination = open('media/uploaded/music/name%s' %(ext), 'wb+')
for chunk in f.chunks():
destination.write(chunk)
destination.close()
{% block main %}
{{band.name}}
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}
{{ form.as_p}}
<input type="submit" value="Add song" />
</form>
{% endblock %}
class SongForm(forms.ModelForm):
band = forms.ModelChoiceField(queryset=Band.objects.all(), widget=forms.HiddenInput)
def clean_audio_file(self):
file = self.cleaned_data.get('audio_file',False)
if file:
if file._size > 10*1024*1024:
raise forms.ValidationError("Audio file too large ( > 10mb)")
if not file.content_type in ["audio/mp3", "audio/mp4"]:
raise forms.ValidationError("Content type is not mp3/mp4")
if not os.path.splitext(file.name)[1] in [".mp3", ".mp4"]:
raise forms.ValidationErorr("Doesn't have proper extension")
else:
raise forms.ValidationError("Couldn't read uploaded file")
class Meta:
model = Song
文件就在媒体/上传/音乐中,但是在admin audio_file是空白的,如果我为audio_file设置了blank = False(这是我想做的),我被告知这个字段是必需的。是什么给了??
提前致谢!现在已经有一段时间了,文档对我来说很轻松(newb)。
答案 0 :(得分:1)
clean_audio_file
应该返回此特定字段的已清理数据,因此您需要向其添加return file
!
就像一般字段
clean()
方法,上面,这个方法应该 无论如何,都要返回已清理的数据 是否有任何改变。
答案 1 :(得分:1)
据我所知,您不需要handle_uploaded_file()
。您正在使用ModelForm
和models.FileField
。它支持upload_to
参数,并自动将文件保存到目标。
从Django文档上传example的基本文件正在使用Form
和forms.FileField
,因此它涉及handle_uploaded_file()
函数。
所以,试着简单地删除这一行:
handle_uploaded_file(request.FILES['audio_file'])
从您的观点来看,请告诉我们会发生什么。
编辑:另外,@ lazerscience是对的,你需要添加
return self.cleaned_data
在clean_audio_file()
的末尾。 (但不是 return file
,因为即使您只清理一个字段,也总是应该返回整个清理过的数据字典。)