【问题标题】:How to access the Django forms.FileField file (*not models.FileField*)?如何访问 Django forms.FileField 文件(*不是 models.FileField*)?
【发布时间】:2015-01-03 17:08:54
【问题描述】:

我正在运行 Django 1.7。

我有以下模型形式:

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

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

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

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

编辑:

我想知道如何让它与基于通用类的创建视图一起使用,该视图使用上述模型形式 - 在 vi​​ews.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 中重写的方法来处理文件上传?

【问题讨论】:

标签: python django django-forms django-1.7


【解决方案1】:

我发现对于新的 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 时。

【讨论】:

  • Aus_lacy - 谢谢,这几乎是我需要的一切。您能否简要评论一下如何修改该示例以使用基于分类的创建视图(请参阅对我的问题的编辑)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 2020-09-17
相关资源
最近更新 更多