为什么我的文件不保存到实例(它保存到磁盘......)?

发布于 2024-11-16 22:38:14 字数 2497 浏览 3 评论 0原文

我可以将我的文件保存到我指定的磁盘上,但无法将其保存到实例中,我根本不知道为什么!

models.pyviews.pyhandle_uploaded_filesong_upload.html

    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 %}

forms.py

    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

该文件就在media/uploaded/music中,但在管理中audio_file是空白的,如果我设置blank=False(这就是我想要 do) 对于audio_file,我被告知该字段是必需的。什么给?

提前致谢!已经从事这个工作有一段时间了,文档对我来说似乎很轻松(新手)。

I can get my file to save to disk where I tell it to, but can't get it to save to the instance and I haven't the slightest idea why!

models.py

    class Song(models.Model):
        name = models.CharField(max_length=50)
        audio_file = models.FileField(upload_to='uploaded/music/', blank=True)

views.py

    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))

handle_uploaded_file

    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()

song_upload.html (relevant part)

    {% 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 %}

forms.py

    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

The file is right there in media/uploaded/music, but in admin audio_file is blank, and if i set blank=False (which is what I want to do) for audio_file, I'm told this field is required. What gives??

Thanks in advance! Been at this one for a while now, docs seem light to me (newb).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你在看孤独的风景 2024-11-23 22:38:14

clean_audio_file 应返回此特定字段的已清理数据,因此您需要向其中添加一个返回文件

来自 django 的文档

就像一般字段clean()
方法,上面,这个方法应该
返回清理后的数据,无论
它是否改变了什么。

clean_audio_file should return the cleaned data for this specific field, so you will need to add a return file to it!

From django's documentation:

Just like the general field clean()
method, above, this method should
return the cleaned data, regardless of
whether it changed anything or not.

那请放手 2024-11-23 22:38:14

据我所知,您不需要handle_uploaded_file()。您正在使用 ModelFormmodels.FileField。它支持upload_to参数,并自动将文件保存到目的地。

基本文件上传 示例< Django 文档中的 /a> 使用 Formforms.FileField,因此它涉及到handle_uploaded_file()函数。

因此,尝试简单地删除这一行:

handle_uploaded_file(request.FILES['audio_file'])

从您的角度来看,请告诉我们接下来会发生什么。

编辑:另外,@lazerscience 是对的,您需要

return self.cleaned_data

clean_audio_file() 的末尾添加。 (但是返回文件,因为即使您只清理一个字段,您也始终应该返回整个已清理的数据字典。)

As far as I know, you don't need to handle_uploaded_file(). You're using ModelForm and models.FileField. It supports upload_to argument, and saves the file to the destination automatically.

The basic file uploading example from Django docs is using Form and forms.FileField, and because of that it involves handle_uploaded_file() function.

So, try to simply remove this line:

handle_uploaded_file(request.FILES['audio_file'])

from your view and please tell what happens then.

EDIT: Also, @lazerscience is right, you need to add

return self.cleaned_data

at the end of your clean_audio_file(). (But not return file, since you always should return the whole cleaned data dictionary even if you're cleaning just one field.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文