代码之家  ›  专栏  ›  技术社区  ›  Joeyohanlin

流模板给出错误“jinja2.exceptions.UndefinedError:'stockStatus'未定义”

  •  0
  • Joeyohanlin  · 技术社区  · 2 年前

    我正在关注 tutorial 关于如何使用Python-Flask框架创建webhook。webhook旨在实现客户端(webhook生成器)和服务器(webhook-listener)之间的通信。服务器有一个文件,其中包含产品的库存单位和库存状态(“库存中”或“缺货”)。目标是允许客户端通过向服务器发送HTTPPOST请求来检索特定产品的库存状态。但是,我无法为webhook监听器加载页面( consumer.html )并接收到以下错误:

    Traceback (most recent call last):
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 2213, in __call__      
        return self.wsgi_app(environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask_socketio\__init__.py", line 43, in __call__
        return super(_SocketIOMiddleware, self).__call__(environ,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\engineio\middleware.py", line 74, in __call__
        return self.wsgi_app(environ, start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 2193, in wsgi_app      
        response = self.handle_exception(e)
                   ^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 2190, in wsgi_app      
        response = self.full_dispatch_request()
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 1486, in full_dispatch_request
        rv = self.handle_user_exception(e)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request
        rv = self.dispatch_request()
             ^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 1469, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\Documents\GitHub\Gelato-API-webhooks\inventory\app_consumer.py", line 18, in index
        return render_template('consumer.html')
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\templating.py", line 151, in render_template
        return _render(app, template, context)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\templating.py", line 132, in _render 
        rv = template.render(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\jinja2\environment.py", line 1301, in render
        self.environment.handle_exception()
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\jinja2\environment.py", line 936, in handle_exception
        raise rewrite_traceback_stack(source=source)
      File "C:\Users\yuanl\Documents\GitHub\Gelato-API-webhooks\inventory\templates\consumer.html", line 16, in top-level template code
        {% for SKU, Stock_status in stockStatus.items() %}
      File "C:\Users\yuanl\AppData\Local\Programs\Python\Python311\Lib\site-packages\jinja2\environment.py", line 485, in getattr
        return getattr(obj, attribute)
               ^^^^^^^^^^^^^^^^^^^^^^^
    jinja2.exceptions.UndefinedError: 'stockStatus' is undefined
    

    的代码 consumer.html Jinja模板文件如下所示:

    <!doctype html>
    <html>
      <head>
        <title>Tasks Producer</title>
        <link href="../styles/style.css" rel="stylesheet">
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
      </head>
      <body class="container">
        <h1>Stock Sheet</h1>
        <table id="stockSheet">
          <tr>
            <th scope="col">SKU</th>
            <th scope="col">Stock Status</th>
          </tr>
        </table>
        {% for SKU, Stock_status in stockStatus.items() %}
            <script>
              var SKU = "{{SKU}}";
              var Stock_status = "{{Stock_status}}";
              document.getElementById("stockSheet").innerHTML += "<tr>" + "<td>"+ SKU + "</td>" + "<td>"+ Stock_status + "</td>" + "</tr>"
            </script>
        {% endfor %}
      </body>
    </html>
    

    该文件中的错误是 stockStatus 未定义。但是,变量是在 app_consumer.py 渲染和流式传输Jinja模板文件的文件,特别是 return Response(render_template_stream('consumer.html', stockStatus = tasks_consumer.sendStockStatus())) 陈述文件中的相关代码段如下所示:

    from flask import Response, render_template, request
    from flask_socketio import join_room
    from init_consumer import app, socketio
    import tasks_consumer
    import uuid
    
    # Render a template with a given context as a stream and return a TemplateStream
    def render_template_stream(template_name, **context):
        app.update_template_context(context)
        t = app.jinja_env.get_template(template_name)
        rv = t.stream(context)
        rv.enable_buffering(5)
        return rv
    
    # Render the assigned template file
    @app.route("/", methods=['GET'])
    def index():
        return render_template('consumer.html')
    
    # Registers a function to be run before the first request to this instance of the application
    # Create a unique session ID and store it within the application configuration file
    @app.before_request
    def initialize_params():
        if not hasattr(app.config,'uid'):
            sid = str(uuid.uuid4())
            app.config['uid'] = sid
            print("initialize_params - Session ID stored =", sid)
    
    @app.route('/consumetasks', methods=['POST'])
    def get_stock_status():
        print("Retrieving stock status")
        return Response(render_template_stream('consumer.html', stockStatus = tasks_consumer.sendStockStatus()))            
    

    的代码 tasks_consumer.py 定义 sendStockStatus() 功能如下所示:

    import csv
    from flask import request
    from init_consumer import app, socketio
    import json
    
    # Receive the webhook requests and emit a SocketIO event back to the client
    def send_message(data):
        status_code = 0
        if request.method == 'POST':
            roomid = app.config['uid']
            msg = json.dumps(data)
            event = "Send_stock_status"
            socketio.emit(event, msg, namespace = '/collectHooks', room = roomid)
            status_code = 200
        else:
            status_code = 405 # Method not allowed
        return status_code
        
    # Retrieve the stock status of the products sent through the webhook requests and return them back to the client.   
    def sendStockStatus():
        SKUlist = []
        stockSheet = {}
        with open("NZ_NVJ_Apparel_SKUs_sheet.csv", newline='') as csvFile:
            stockReader = csv.reader(csvFile, delimiter=',', quotechar='"')
            for row in stockReader:
                SKUlist.append(row[0])
        if request.method == 'POST':
            stockInfo = request.json
            stockStr = str(stockInfo)
            stockStr = stockStr.replace("\'", "\"")
            stockDict = json.loads(stockStr)
            for stock in stockDict["SKU"]:
                if stock in SKUlist:
                    stockSheet.update({str(stock):"In Stock"})
                else:
                    stockSheet.update({str(stock):"Out of Stock"})
        send_message(stockSheet)
        return stockSheet
    

    我不明白是什么导致了这个错误。我在Jinja模板文件中使用了与 Jinja documentation 以及在 库存状态 由返回的词典 sendStockStatus() 中的函数 tasks_consumer.py 文件有人能给我指正确的方向吗?

    0 回复  |  直到 2 年前