Jinja2 UndefinedError - HTML 函数调用不起作用

问题描述 投票:0回答:1

我正在使用 Flask 和 SQLAlchemy 开发杂货店 Web 应用程序 我正在尝试将产品打印为卡片,排列在各自的类别下 但后来我得到了这个错误。我似乎无法弄清楚错误是什么。所有函数和变量似乎都被完美声明。

这是app.py的代码块

return Product.query.filter_by(category_id=category_id).all()
@app.route('/')
def index():
categories = Category.query.all()
products = Product.query.order_by(Product.id.desc()).limit(10).all()
return render_template('index.html', categories=categories, products=products)

index.html 中的代码块


    {% extends "base.html" %}
    
    {% block content %}
    <div class="container mt-5">
        {% for category in categories %}
        <h2>{{ category.name }}</h2>
        <div class="row">
            {% set category_products = get_products_by_category(category.id) %}
            {% for product in category_products %}
                        <div class="col-md-4 mb-4">
                        <div class="card">
                            <div class="card-body">
                                <h5 class="card-title">{{ product.name }}</h5>
                                <p class="card-text">Price: {{ product.price }}</p>
                                {% if 'user_id' in session %}
                                    <form action="{{ url_for('add_to_cart', product_id=product.id) }}" method="post">
                                        <button class="btn btn-primary" type="submit">+</button>
                                    </form>
                                    <form action="{{ url_for('remove_from_cart', product_id=product.id) }}" method="post">
                                        <button class="btn btn-danger" type="submit">-</button>
                                    </form>
                                {% else %}
                                    <p><a href="{{ url_for('login') }}">Log in</a> to add products to your cart</p>
                                {% endif %}
                            </div>
                        </div>
                    </div>
                {% endfor %}
            </div>
        {% endfor %}
    </div>
    
    {% endblock %}

这是回溯:

return self.wsgi_app(environ, start_response)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 2193, in wsgi_app
response = self.handle_exception(e)
           ^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 2190, in wsgi_app
response = self.full_dispatch_request()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\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\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request
rv = self.dispatch_request()
     ^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\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\Admin\Desktop\Ananyaa\MAD1\app.py", line 71, in index
return render_template('index.html', categories=categories, products=products)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\templating.py", line 151, in render_template
return _render(app, template, context)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\templating.py", line 132, in _render
rv = template.render(context)
     ^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\jinja2\environment.py", line 1301, in render
self.environment.handle_exception()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Admin\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\Admin\Desktop\Ananyaa\MAD1\template\index.html", line 11, in top-level template code
{% extends "base.html" %}
File "c:\Users\Admin\Desktop\Ananyaa\MAD1\template\base.html", line 28, in top-level template code
{% block content %}
File "c:\Users\Admin\Desktop\Ananyaa\MAD1\template\index.html", line 18, in block 'content'
{% set category_products = get_products_by_category(category.id) %}
File "C:\Users\Admin\AppData\Local\Programs\Python\Python311\Lib\site-packages\jinja2\utils.py", line 83, in from_obj
if hasattr(obj, "jinja_pass_arg"):
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
jinja2.exceptions.UndefinedError: 'get_products_by_category' is undefined```

有人可以帮我指出错误吗?

html flask flask-sqlalchemy sqlite3-python
1个回答
0
投票

jinja 中不知道

get_products_by_category
功能。
如果不将 Jinja 定义的函数分配给 Jinja 环境全局变量或通过
render_template
将其传递给模板,则无法使用 Jinja 中定义的函数。

app.jinja_env.globals.update(get_products_by_category=get_products_by_category)

但是,在您的示例中,我认为除了使用外键之外,在两个数据库模型Category

Product
之间定义
关系
更有意义。
以下示例向您展示了将
relationship
backref
属性结合使用以使该类别的产品易于访问的可能性。

class Product(db.Model):
    __tablename__ = 'products'

    id = db.Column(db.Integer, primary_key=True)
    
    # ...

    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    category = db.relationship('Category', backref='products')

class Category(db.Model):
    __tablename__ = 'categories'

    id = db.Column(db.Integer, primary_key=True)

    # ...

模板内的迭代将如下所示。

<div class="container mt-5">
    {% for category in categories -%}
    <!-- ... -->
    <div class="row">
        {% for product in category.products -%}
        {# Use the respective product of the category here. #}
        <!-- ... -->
        {% endfor -%}
    </div>
    {% endfor -%}
</div>
© www.soinside.com 2019 - 2024. All rights reserved.