【问题标题】:django - how to parse an uploaded file and send the result to a different formdjango - 如何解析上传的文件并将结果发送到不同的表单
【发布时间】:2015-03-23 21:19:23
【问题描述】:

我是 django 新手,在我的第一个应用程序中,
我想上传一个行数未知的 csv 文件,解析它的内容并显示解析后的数据,然后处理这些数据并将其保存在表格中。

实现这一目标的最佳方法是什么?

目前我有一个用于上传文件的视图和表单,
我的第一次尝试是在该视图中解析上传的文件并将解析后的数据发送到第二个视图:

def UploadFileView(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            upload_list = handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect(reverse('preview_file', ?????))
    else:
        form = UploadFileForm()

    return render(request, 'upload_file.html', {'form': form,})

upload_list - 描述文件中一行的对象列表。
????? - 在这里放置什么以发送列表到第二个视图?

我知道我需要以某种方式序列化此列表,以便能够将其发送到第二个视图,即 preview_file

  1. 如何序列化它?将其设为 JSON 字符串?
  2. 如何将此序列化数据发送到第二个视图?

csv 文件的行数未知,可以是 3、10 或 500。

在发布这个问题时,我想到了另一种选择,并想知道它是否可能以及它是否是一个更好的选择:
不是在第一个视图中解析文件,而是将其发送到第二个视图并在该视图中调用 handle_uploaded_file

【问题讨论】:

    标签: django serialization file-upload multiple-forms multiple-views


    【解决方案1】:

    将列表保存到会话中:

    import random
    from django.shortcuts import redirect
    
    key = 'preview%s' % random.randint(0, 999999)
    request.session[key] = upload_list
    return redirect('preview_file', key)
    

    还有prefiew_file()

    from django.http import Http404
    
    def preview_file(request, key):
        upload_list = request.session.get(key)
        if not upload_list:
            raise Http404
    

    更新:会话大小限制取决于使用的SESSION_ENGINE。默认的django.contrib.sessions.backends.db 引擎将会话数据存储在数据库TEXT 字段中。在 Postgres/SQLite 的情况下,此类字段最多可包含 1Gb 的数据。对于 MySQL,限制为 64Kb。

    【讨论】:

    • 谢谢,这确实有效,而且很容易实现,但是你知道会话是否有大小限制吗?
    【解决方案2】:

    您可以为此使用 Django 表单集 (https://docs.djangoproject.com/en/dev/topics/forms/formsets/)。表单集是相同表单的实例的集合。您可以定义一个显示 CSV 文件一行内容的表单,并为其创建一个表单集以显示整个文件。

    在下面的示例中,我使用以下 CSV 文件:

    Name,Email
    Bob,bob@example.com
    Alice,alice@example.com
    

    表示这些数据的形式可能如下(非常简化):

    class PersonForm(forms.Form):
        name = forms.CharField()
        email = forms.EmailField()
    

    要为此创建表单集,请执行以下操作:

    PersonFormSet = formset_factory(PersonForm)
    

    要填充您的表单集,您应该设置初始数据。当您在视图中实例化表单时,您可以这样做:

    def some_view(request):
        # ....
        form = PersonFormSet(
                   initial=[
                       {'name': "Bob", 'email': "bob@example.com"},
                       {'name': "Alice", 'email': "alice@example.com"},
                   ]
               )
    

    或者,使用基于类的视图:

    class SomeView(FormView):
        form_class = PersonFormSet
    
        def get_initial(self):
            return [
                       {'name': "Bob", 'email': "bob@example.com"},
                       {'name': "Alice", 'email': "alice@example.com"},
                   ]
    

    如您所见,一个 dicts 列表就足够了,您只需对 CSV 数据进行最少的操作。

    剩下的挑战是获取表单中的数据。这里有几种方法,但我建议您在同一个视图中处理所有内容或保存文件并传递文件名(尽管后者可能具有安全隐患)。

    【讨论】:

    • 谢谢。我也在调查这个。因为我想将解析后的文件呈现为表格,但要添加几个字段,并且理解的表单集可以帮助我。
    猜你喜欢
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2011-08-28
    相关资源
    最近更新 更多