在Django中保存包含FileField的模型

时间:2015-05-19 07:09:19

标签: django django-models

我有以下型号;

class AudioFile(models.Model):
    name = models.CharField(max_length=100, default='')
    audio_file = models.FileField()
    uploader = models.ForeignKey(User, default='')

    def __unicode__(self):
        return self.name    

以下表格;

class AudioFileForm(forms.ModelForm):
    class Meta:
        model = AudioFile
        fields = ['name', 'audio_file']

    def clean_audio_file(self):
        audio = self.cleaned_data.get('audio_file',False)
        if audio:
            if audio._size > 5*1024*1024:
                raise ValidationError("File too large ( > 5mb )")
            if os.path.splitext(audio.name)[1] != ".mp3":
                raise ValidationError("We only support mp3!")
            return audio
        else:
            raise validationError("Couldn't read uploaded file")

正如您所看到的,有一些自定义验证

然后我将以下html与AudioFileForm传递为form;

<!DOCTYPE html>
<html>
<head>
</head>

<body>
  <form method="post" action="{% url 'actual_upload_audio' %}">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Upload"/>
  </form>
</body>
</html>

现在我知道如果没有包含FileField的对象如何保存。我会做这样的事情;

form = AudioFileForm(request.POST)
if form.is_valid():
    name = form.cleaned_data['name']
    //Say it contained another field, foo
    foo = form.cleaned_data['foo'] 
    uploader = request.user //view requires login
    audio_file = Audio_File.objects.create(name=name,
                                           foo=foo,
                                           uploader=uploader)
    audio_file.save()
    return HttpResponse("Success!")

但是有一个有问题的FileField我不知道如何处理这个问题。我阅读了Django的文档但是没有真正理解它。一个更容易精心设计的解释很可爱。

首先,我MEDIA_ROOT = '/home/afzalsh/works/openradio/audio_files/'

中有settings.py

更新

感谢@Rohan我现在有<form method="post" action="{% url 'actual_upload_audio' %}" enctype="multipart/form-data">而不是<form method="post" action="{% url 'actual_upload_audio' %}">

感谢@dzejdzej;

也有以下观点
form = AudioFileForm(request.POST, request.FILES)
    if form.is_valid():
        form.cleaned_data['uploader'] = request.user
        form.save()
        return HttpResponseRedirect(reverse('home_audio',kwargs={'pk':audio_file.pk}))
    else:
        return HttpResponse("Form Invalid!")

但是Form Invalid!:/

4 个答案:

答案 0 :(得分:3)

您的表单应具有enctype="multipart/form-data"属性,以便提交文件。

<form method="post" action="{% url 'actual_upload_audio' %}"
       enctype="multipart/form-data" >
   ...
 </form>

答案 1 :(得分:1)

既然您正在使用ModelForm,为什么不让Django处理保存整个模型呢?

PATH->Edit-> ADD "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\bin "

如果您使用的是Django&gt; = 1.7,则不再需要upload_to字段。但是,我认为这是一个很好的做法。 https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.FileField.upload_to

成功POST后也会重定向用户,以避免csrf出现问题。

答案 2 :(得分:0)

您应该将upload_to属性提及为:audio_file = models.FileField(upload_to ='uploads')

此处'uploads'是您要将文件上传到的目录的名称。

答案 3 :(得分:0)

作为Rohan seaid,您必须在模板中玷污您的表单。

<form method="post" action="{% url 'actual_upload_audio' %}"
       enctype="multipart/form-data" >
   ...
</form>

这允许您将带有请求的文件发送到view。现在看来你必须有这样的东西:

def my_view(request):
    if request.method == 'POST':
        my_form = MyForm(request.POST, request.FILES)
        if my_form.is_valid():
            my_form.save()

您可以使用 request.FILES

初始化表单FileField和ImageField