【问题标题】:Flask and Jinja2 - Filter is jinja2.exceptions.UndefinedError: 'convert_date_to_name' is undefinedFlask 和 Jinja2 - 过滤器是 jinja2.exceptions.UndefinedError: 'convert_date_to_name' 未定义
【发布时间】:2021-08-21 09:48:03
【问题描述】:

我有一个 Flask Web 应用程序,我在我的 PC 上进行了本地测试。在本地,一切正常 - 没有问题。因此,我继续在 uWSGI 和 Nginx 后面的 Ubuntu 20.04 服务器上部署了我的 Flask 应用程序。我现在面临的问题是,我的 Jinja2 模板自定义过滤器是“未定义”。我完全不确定问题出在哪里。

我得到的错误是:

ERROR:reservationsystem:Exception on / [GET]
Traceback (most recent call last):
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask/app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask/app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask/app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask/app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask_monitoringdashboard/core/measurement.py", line 127, in wrapper
    raise raised_exception
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask_monitoringdashboard/core/measurement.py", line 107, in evaluate
    result = route_handler(*args, **kwargs)
  File "./reservationsystem.py", line 216, in index
    return render_template('index.html', treningy=treningy)
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask/templating.py", line 147, in render_template
    return _render(
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/flask/templating.py", line 128, in _render
    rv = template.render(context)
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/jinja2/environment.py", line 1304, in render
    self.environment.handle_exception()
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/jinja2/environment.py", line 925, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/home/antonio/reservationsystem/templates/index.html", line 60, in top-level template code
    <h3 id="h3forFading">{{ convert_date_to_name(complete_date)[0]|upper }}{{ convert_date_to_name(complete_date)[1:] }}
  File "/home/antonio/reservationsystem/reservationsystem_venv/lib/python3.8/site-packages/jinja2/utils.py", line 84, in from_obj
    if hasattr(obj, "jinja_pass_arg"):
jinja2.exceptions.UndefinedError: 'convert_date_to_name' is undefined

这是定义我的自定义过滤器的 Python Flask 代码的 sn-p:

#Convert date to name function for displaying it in Jinja2 template
def convert_date_to_name(date, format=r'%d-%m-%Y'):
    date = str(date)
    return datetime.datetime.strptime(date, format).strftime('%A')

...
# here are my routes (app.route()) defined
...

#Run Flask instance
if __name__ == "__main__":
    app.jinja_env.globals['convert_date_to_name'] = convert_date_to_name
    app.jinja_env.add_extension('jinja2.ext.loopcontrols')
    app.jinja_env.filters['regex_replace'] = regex_replace
    app.run(host='0.0.0.0', debug=False, threaded=True)

这是我使用自定义过滤器的 Jinja2 模板:

 <h3 id="h3forFading">
{{ convert_date_to_name(complete_date)[0]|upper }}{{ convert_date_to_name(complete_date)[1:] }}
</h3>

我的 Flask 文件 + 虚拟环境所在目录的位置是:

# Flask files
/home/antonio/reservationsystem

#Virtual environment
/home/antonio/reservationsystem/reservationsystem_venv/

/home/antonio/reservationsystem 的结构如下所示:

antonio@addictionclubrezervacnysystemserver:~/reservationsystem$ ls -l
total 516
-rw-rw-r-- 1 antonio antonio     884 Jun  2 19:35 README.md
drwxr-xr-x 2 antonio www-data   4096 Jun  3 10:09 __pycache__
-rw-r--r-- 1 antonio antonio   57344 Jun  3 10:06 db_reservationsystem.db
-rw-r--r-- 1 antonio antonio   61440 Jun  3 10:42 flask_monitoringdashboard.db
-rw-rw-r-- 1 antonio antonio   18649 Jun  2 19:35 helpers.py
-rw-rw-r-- 1 antonio antonio      40 Jun  2 19:35 requirements.txt
-rw-rw-r-- 1 antonio antonio     163 Jun  2 19:43 reservationsystem.ini
-rw-rw-r-- 1 antonio antonio  119336 Jun  3 10:09 reservationsystem.py
srw-rw---- 1 antonio www-data      0 Jun  3 10:24 reservationsystem.sock
drwxrwxr-x 6 antonio antonio    4096 Jun  2 19:39 reservationsystem_venv
drwxrwxr-x 2 antonio antonio    4096 Jun  2 19:56 scripts
-rw-rw-r-- 1 antonio antonio    1311 Jun  2 19:35 start_everything.py
drwxrwxr-x 4 antonio antonio    4096 Jun  2 19:35 static
drwxrwxr-x 4 antonio antonio    4096 Jun  2 19:35 templates
-rw-rw-r-- 1 antonio antonio      76 Jun  2 19:41 wsgi.py
antonio@addictionclubrezervacnysystemserver:~/reservationsystem$ 

我的 uWSGI 和 Nginx .ini 文件如下所示:

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = reservationsystem.sock
chmod-socket = 660
vacuum = true

die-on-term = true
enable-threads = true

我的 wsgi.py 文件如下所示:

from reservationsystem import app

if __name__ == "__main__":
    app.run()

我的服务定义如下所示:

[Unit]
Description=uWSGI instance to serve Flask web app
After=network.target

[Service]
User=antonio
Group=www-data
WorkingDirectory=/home/antonio/reservationsystem/
Environment="PATH=/home/antonio/reservationsystem/reservationsystem_venv/bin"
ExecStart=/home/antonio/reservationsystem/reservationsystem_venv/bin/uwsgi --ini reservationsystem.ini

[Install]
WantedBy=multi-user.target

最后,我的 Nginx 配置如下:

server {
    server_name mydomain.com www.mydomain.com;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/antonio/reservationsystem/reservationsystem.sock;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/trening.addictionclub.sk/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/trening.addictionclub.sk/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name mydomain.com www.mydomain.com;
    return 404; # managed by Certbot


}

对我来说,我的 Flask Web 应用程序的服务似乎在不同的文件夹中运行,然后,我的模板无法将 convert_date_to_name() 函数导入 Jinja2 模板本身(尽管我不确定这真的是问题在这里。这只是我有根据的猜测。)。

非常感谢任何想法和帮助。

谢谢。

【问题讨论】:

    标签: python flask uwsgi


    【解决方案1】:

    问题在于 wsgi.py

    from reservationsystem import app
    
    if __name__ == "__main__":
        app.run()
    

    它正在启动应用程序而不初始化它。 if __name__ == "__main__":下的代码 不会被执行,

    也许你应该使用工厂模式来创建应用程序并在 create_app() 方法中初始化 jinja。

    https://flask.palletsprojects.com/en/2.0.x/patterns/appfactories/

    或者你可以更新你的文件并在顶层初始化 jinja

    from flask import Flask
    app = Flask(__name__)
    app.jinja_env.globals['convert_date_to_name'] = convert_date_to_name
    app.jinja_env.add_extension('jinja2.ext.loopcontrols')
    app.jinja_env.filters['regex_replace'] = regex_replace
    
    #Convert date to name function for displaying it in Jinja2 template
    def convert_date_to_name(date, format=r'%d-%m-%Y'):
        date = str(date)
        return datetime.datetime.strptime(date, format).strftime('%A')
    
    ...
    # here are my routes (app.route()) defined
    ...
    
    #Run Flask instance
    if __name__ == "__main__":
        app.run(host='0.0.0.0', debug=False, threaded=True)
    

    【讨论】:

    • 嗯,据说是这样的:digitalocean.com/community/tutorials/…
    • 然后在app对象可用后尝试将jinja初始化移到顶部。
    • 我不确定你的意思,因为我的主 Flask 文件 (reservationsystem.py) 中有这个:``` #Run Flask instance if name == "main": app.jinja_env.globals['convert_date_to_name'] = convert_date_to_name app.jinja_env.add_extension('jinja2.ext.loopcontrols') app.jinja_env.filters['regex_replace'] = regex_replace app .run(host='0.0.0.0', debug=False, threaded=True) ```
    • 您的答案的更新/编辑版本帮助了我!它也与这个答案有某种联系:stackoverflow.com/questions/24643530/… 谢谢@Talha Junaid!
    猜你喜欢
    • 1970-01-01
    • 2018-03-11
    • 2020-12-24
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多