Flask和Jinja2过滤器为Jinja2.exceptions.UndelineError:“convert_date_to_name”未定义

2024-09-28 23:38:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Flask web应用程序,我在我的PC上进行了本地测试。在本地,一切正常-没有问题。因此,我继续前进,在uWSGI和Nginx后面的Ubuntu20.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代码片段:

#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的My.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模板本身(尽管我不确定这是否真的是问题所在。这只是我的猜测)

非常感谢您的任何想法和帮助

多谢各位


Tags: nameinpyapphomedatevenvlib
1条回答
网友
1楼 · 发布于 2024-09-28 23:38:58

问题在于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)

相关问题 更多 >