Почему мой файл не сохраняется в экземпляр (он сохраняется на диск ...)? - PullRequest
4 голосов
/ 25 июня 2011

Я могу получить свой файл для сохранения на диск, куда я говорю, но не могу сохранить его для экземпляра, и у меня нет ни малейшего представления, почему!

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 (соответствующая часть)

    {% 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, но в admin audio_file пуст, и если я установлю blank = False (именно это я и хочу сделать) для audio_file, мне сказали этоПоле, обязательное для заполнения.Что дает ??

Заранее спасибо!Некоторое время назад мне показалось, что документы кажутся легкими (новичок).

Ответы [ 2 ]

1 голос
/ 26 июня 2011

Насколько я знаю, вам не нужно handle_uploaded_file(). Вы используете ModelForm и models.FileField. Он поддерживает аргумент upload_to и автоматически сохраняет файл в месте назначения.

Базовая загрузка файлов пример из Django docs использует Form и forms.FileField, и поэтому включает в себя функцию handle_uploaded_file().

Итак, попробуйте просто удалить эту строку:

handle_uploaded_file(request.FILES['audio_file'])

с вашей точки зрения и, пожалуйста, расскажите, что происходит потом.

РЕДАКТИРОВАТЬ: Кроме того, @lazerscience правильно, вам нужно добавить

return self.cleaned_data

в конце вашего clean_audio_file(). (Но не return file, поскольку вы всегда должны возвращать весь словарь очищенных данных, даже если вы чистите только одно поле.)

1 голос
/ 26 июня 2011

clean_audio_file должен вернуть очищенные данные для этого конкретного поля, поэтому вам нужно будет добавить return file к нему!

Из документации django :

Так же, как и метод общего поля clean(), описанный выше, этот метод должен возвращать очищенные данные независимо от того, изменилось ли что-либо или нет.

...