使用会话在Django中将文件从一个视图传递到另一个视图

时间:2014-12-11 15:36:13

标签: python django session

我当前的工作项目要求我允许用户上传各种格式的文件(目前只处理CSV格式),然后使用包含的数据使用Pandas库绘制图表。

我已经决定将图形呈现给模板的最简单方法是为图形创建特定视图,然后将图像从所需模板链接到该视图(例如,包含文件上载的表单页面) 。我的工作是使用我硬编码的本地路径的文件,但我似乎无法将上传的文件传递给图表视图。我读到使用会话是最简单的方法,但我的尝试并没有成功。

以下代码属于我的文件上传表单视图,其中包含以下错误:

错误#1

InMemoryUploadedFile: sampleCSV.csv (application/vnd.ms-excel) is not JSON serializable
# upload files
@login_required
def list(request):
    # handle file upload
    if request.method == 'POST':
        form = FileUploadForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = FileUpload(docFile = request.FILES['docFile'])
            newdoc.save();
            request.session['docFile'] = request.FILES['docFile']   
            return HttpResponseRedirect(reverse('list'))
    else:
        form = FileUploadForm()

    # render list page
    return render_to_response(
        'graphite/list.html',
        { 'form': form },
        context_instance=RequestContext(request)
    )

我的图表视图显示如下错误:

错误#2

Expected file path name or file-like object, got class 'NoneType' type

# graph input file
def graph(request):
    new_file = request.session.get('docFile')
    fig = Figure()
    ax = fig.add_subplot(111)
    data_df = pd.read_csv(new_file)
    data_df = pd.DataFrame(data_df)
    data_df.plot(ax=ax)
    canvas = FigureCanvas(fig)
    response = HttpResponse( content_type = 'image/png')
    canvas.print_png(response)
    return response

关于我明显做错了什么或者我能做些什么不同的任何想法都将不胜感激。感谢。


修改

根据我的建议我试图存储文件的名称,然后通过会话传递,但也无济于事。当前错误与上面列出的错误相同。我的实现如下:

Models.py

class FileUpload(models.Model):
    docFile = models.FileField(upload_to='Data_Files', blank=True)

    @property
    def filename(self):
        return os.path.basename(self.docFile.name)

文件上传视图

# upload files
@login_required
def list(request):
    # handle file upload
    if request.method == 'POST':
        form = FileUploadForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = FileUpload(docFile = request.FILES['docFile'])
            newdoc.save();
            request.session['docFile'] = newdoc.filename    
            return HttpResponseRedirect(reverse('list'))
    else:
        form = FileUploadForm()

    # render list page
    return render_to_response(
        'graphite/list.html',
        { 'form': form },
        context_instance=RequestContext(request)
    )

图表视图

# graph input file
def graph(request):
    new_file = request.session.get('docFile')
    fig = Figure()
    ax = fig.add_subplot(111)
    data_df = pd.DataFrame.from_csv(new_file)
    data_df.plot(ax=ax)
    canvas = FigureCanvas(fig)
    response = HttpResponse( content_type = 'image/png')
    canvas.print_png(response)
    return response

上述错误的回溯:

Traceback:
File "C:\Python34\lib\site-packages\django-1.7.1-py3.4.egg\django\core\handlers\base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\vut46744\Desktop\graphite_project\graphite\views.py" in graph
  127.  data_df = pd.DataFrame.from_csv(new_file)
File "C:\Python34\lib\site-packages\pandas\core\frame.py" in from_csv
  1027.                           infer_datetime_format=infer_datetime_format)
File "C:\Python34\lib\site-packages\pandas\io\parsers.py" in parser_f
  465.         return _read(filepath_or_buffer, kwds)
File "C:\Python34\lib\site-packages\pandas\io\parsers.py" in _read
  241.     parser = TextFileReader(filepath_or_buffer, **kwds)
File "C:\Python34\lib\site-packages\pandas\io\parsers.py" in __init__
  557.         self._make_engine(self.engine)
File "C:\Python34\lib\site-packages\pandas\io\parsers.py" in _make_engine
  694.             self._engine = CParserWrapper(self.f, **self.options)
File "C:\Python34\lib\site-packages\pandas\io\parsers.py" in __init__
  1056.         self._reader = _parser.TextReader(src, **kwds)

2 个答案:

答案 0 :(得分:2)

我认为您不能将file对象放入会话中,因为它不可序列化,存储其文件名并在graph视图中重新打开该文件

答案 1 :(得分:0)

Django使用pickle对会话对象进行序列化/反序列化。

如果您无法重构代码并在列表视图中添加响应,则可以存储文件并稍后使用python io API检索它们。

从文档中,pickle的序列化接受类型是:

无,真,假 整数,长整数,浮点数,复数 普通和Unicode字符串元组,列表,集合和 仅包含可选对象的字典 在模块顶层定义的函数 在模块顶层定义的内置函数 在模块顶层定义的类 此类的实例 dict 或调用 getstate ()的结果是可选择的