传递类

时间:2018-02-22 03:42:22

标签: python flask

我正在开发一个小型网络应用程序来创建一些图表,我需要创建一个变量来保存每个Web应用程序会话的唯一文件名,以便用户不会收到错误的文件当他们将图表保存为pdf时。为此,我使用flask_classful将相关视图包装在一个类中,并创建了一个实例变量来保存文件名。

class PiperView(FlaskView):
    route_base = '/'

    def __init__(self):
        self.piper_name = '_init_.pdf'

        self.tst_index = 0
        self.tst_plot = 0
        self.tst_download = 0
        self.tst_master = 0

    @route('/',methods=['GET','POST'])
    @route('/index/',methods=['GET','POST'],endpoint='index')
    @nocache
    def index(self):
        self.piper_name = '_piper.pdf'

        #test Code
        #=======================================================================
        file = open(fpath+'index.txt','a')
        self.tst_index += 1
        self.tst_master += 1
        file.write(str(self.tst_index)+"."+str(self.tst_master)+") " +str(self.piper_name)+', ')
        file.close() 
        #=======================================================================

        plot_data = np.loadtxt('piper_data.csv', delimiter=',', skiprows=1 )
        html_plot = Markup(piper(plot_data, ' ', alphalevel=1.0, color=False, file_nam=self.piper_name))
        return render_template('plot.html',title='The Plot', figure=html_plot)

    @route('/plot',methods=['GET','POST'],endpoint='plot')
    @nocache
    def plot(self):
        self.piper_name = str(random.randint(0,10000001))+'_piper.pdf'

        #test Code
        #=======================================================================
        file = open(fpath+'plot.txt','a')
        self.tst_plot += 1
        self.tst_master += 1
        file.write(str(self.tst_plot)+"."+str(self.tst_master)+" ) " +str(self.piper_name)+', ')
        file.close() 
        #=======================================================================

        try:
            f = request.files['data_file']
            plot_data = np.loadtxt(f, delimiter=',', skiprows=1 )
            html_plot = Markup(piper( plot_data, ' ', alphalevel=1.0, color=False, file_nam=self.piper_name))
            return render_template('plot.html',title='The Plot', figure=html_plot)
        except:
            return render_template('plot.html',title='The Plot', figure="There Seems To Be A Problem With Your Data")     


    @route('/download',methods=['GET','POST'],endpoint='download')
    @nocache
    def download(self):
        #test Code
        #=======================================================================
        file = open(fpath+'download.txt','a')
        self.tst_download += 1
        self.tst_master += 1
        file.write(str(self.tst_download)+"."+str(self.tst_master)+") " +str(self.piper_name)+', ')
        file.close()
        #=======================================================================

        return send_from_directory(directory=fpath,filename=self.piper_name)

问题是保存文件名的实例变量不能在方法之间共享。我添加了一些测试代码,试图弄清楚发生了什么。 ' tst_index',' tst_plot' ' tst_download' 每个都按预期行事,因为它们会增加但' tst_master' 在方法调用之间不会增加。

测试代码的输出为:

index.txt
1.1)_piper.pdf,

plot.txt
1.1)7930484_piper.pdf,2.2)9579691_piper.pdf,

download.txt
1.1) init .pdf,2.2) init .pdf,

当我调用索引视图一(1)次时,绘图视图两(2)次和下载视图(2)次。如您所见,' tst_master' 实例变量未在方法调用之间进行更新。

我知道这可以在普通的python中运行,因为我测试了它但是我错过了关于flask和flask_classful导致这种情况的原因吗?

2 个答案:

答案 0 :(得分:0)

在您的应用程序中嵌入这样的状态通常是一个坏主意。无法保证生成响应的视图实例将持续多于该一个请求。将数据存储在flask-server-side之外的数据库,键值存储,甚至是磁盘上的某个文件或浏览器中的客户端。 Flask有许多插件可以让您更轻松(flask-sqlalchemyflask-sessionflask-redis等。

Flask本身提供flask.session对象,该对象将信息存储在客户端的cookie中。 flask-session可能会做你想要的,而不需要额外的开销,如果你担心存储服务器端的东西。只需使用文件系统会话界面对其进行配置,您就会得到一个flask.session变量,它可以处理将用户请求链接到存储在文件系统上的数据的所有魔力。

答案 1 :(得分:0)

You are overcomplicating your task. You probably don't need to use flask-classful for it.

You can use ordinary flask sessions. Session is unique for each user. The only thing you need is to use some unique ID for each file. This file id can be user id if your users log in into your web app and their credentials are stored in the db. Or you can randomly generate this file id. Then you can store the filename in the flask session like this:

from flask import session
...

def plot(...):

    session['user_file_name'] = user_file_name


def download(...):

    user_file_name = session['user_file_name']

Hope this helps.