如何访问Django forms.FileField文件(* not models.FileField *)?

时间:2015-01-03 17:08:55

标签: python django django-forms django-1.7

我正在运行Django 1.7。

我有以下模型形式:

class DeckCreateForm(forms.ModelForm):
    csv_file = forms.FileField(required=False)
    class Meta:
        model = Deck
        fields = ['title', 'description']

请注意,文件字段不是模型的一部分(我想保持这种方式)。此文件字段旨在提供构建模型Deck的替代方法。

我想知道如何访问上传的文件。我查看了我的媒体目录,但它不存在。我尝试将“upload_to”添加到csv_file构造函数中,但出现错误:

TypeError: __init__() got an unexpected keyword argument 'upload_to'

编辑:

我想知道如何使用基于泛型类的创建视图来使用上面的模型形式 - 在views.py中我有:

class DeckCreateView(CreateView):
    model = Deck
    form_class = DeckCreateForm
    template_name = 'deck_create.html'

具体来说,如何修改http://docs.djangoproject.com/en/1.7/topics/http/file-uploads之类的内容以使用上述基于类的视图。我的urls.py文件:

urlpatterns = patterns(
    ...
    url(r"^deck/create/$", views.DeckCreateView.as_view(), name="deck-create"),
    ...
)

是否有一种方法可以在DeckCreateView中覆盖以处理文件上传?

1 个答案:

答案 0 :(得分:0)

我发现有关文件上传的Django文档对于较新的Django用户来说可能有点难以理解。但是,我认为以下链接提供了一个非常简洁易懂的设置文件上传表单的逐步过程。

Need a minimal Django file upload example

我相信你会找到你需要的一切。

修改

为了回应OP关于基于类的视图的编辑和评论,我相信他们可以比基于功能的视图更清晰,更可说“更干净”的代码。这是一个讨论CBV和FBV的很好的链接,其中包括一个简单但有效的CBV示例。

http://www.datalifebalance.com/2014/04/django-file-uploads-with-class-based-views.html

编辑附录

为了完整起见,并限制答案对上述外部链接的依赖性(可能会在某一天消失),我们会添加更多细节。为了实现他们的目标,OP可以覆盖DeckCreateView的post方法并保存DeckCreateForm的__init__,如下所示:

views.py:

...

class DeckCreateView(CreateView):
    ...
    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect(self.success_url)
        else:
            return render(request, self.template_name, {'form': form})

forms.py

...

class DeckCreateForm(forms.ModelForm):
    ...
    def __init__(self, post_data, files_data):
        self.csv_file = files_data.get('csv_file', None)
        return super(DeckCreateForm, self).__init__(post_data, files_data)

    def save(self, *args, **kwargs):
        deck = super(DeckCreateForm, self).save(*args, **kwargs)
        self.handle_csv_file(self.csv_file, deck)
        return deck

    def handle_csv_file(f, deck):
        ...
        for chunk in f.chunks():
            ... 
        ...

表单提交后,会向DeckCreateView :: post发送请求。调用DeckCreateForm :: save时会发生文件处理。