猿问

在 Jinja2 和 Flask 之间传递自定义 python 对象

我是 Flask、Jinja2 和 HTML 模板的新手,我正在尝试学习如何在控制器和视图之间来回传递信息。基本上,我有一个事件日历。每个事件名称都是一个超链接,用于url_for转至包含有关该事件的更多信息的视图。但是,尽管我可以轻松地将自定义事件对象列表传递到 HTML 文件中,但我不知道如何将选定的事件对象返回到控制器。据我所知,该对象正在变成一个字符串。下面的简化代码。


app.py


from flask import Flask, render_template, url_for


app = Flask(__name__)


class Event(object):

    def __init__(self, name, date):

        self.name = name

        self.date = date


events = [Event('event1', '2020-04-11')]


@app.route('/')

def index():

    return render_template('index.html', events=events)



@app.route('/event/<event>')

def event(event):

    return render_template('event.html', event=event)

索引.html


<!DOCTYPE html>

<html>

<body>

    {% for event in events %}

        <a href={{ url_for('event', event=event) }}>{{ event.name }}</a>

    {% endfor %}

</body>

</html>

事件.html


<!DOCTYPE html>

<html>

<body>

    <p>{{ event.name }} {{ event.date }}</p>

</body>

</html>

单击该事件会将我带到一个空白页面,大概是因为 event.html 正在尝试获取不存在的字符串对象的属性。

当将 python 对象传递到视图中如此简单时,似乎有一种同样简单的方法可以将其从视图中返回。请赐教!


哈士奇WWW
浏览 128回答 3
3回答

慕娘9325324

@app.route('/event/<event>')<event>,在本例中,是一个字符串。通常,您会在此处拥有某种 ID,可用于查找对象(可能在数据库中)。在这种情况下,您可以将该 ID 传递到其中url_for(),从而生成类似 的 URL /events/123。然后,当您的event路由被调用时,它会在参数中获得 ID event。然后由您来查找正确的对象并将其传递到您的模板中。

元芳怎么了

当您收到<event>, 只是一个字符串,而不是一个对象。所以你应该在你的数据库中找到事件ID,比如@app.route('/event/<event>')def event(event):&nbsp; &nbsp; e=db.find_event(event) # event is the event number or id&nbsp;&nbsp; &nbsp; if e:&nbsp; &nbsp; &nbsp; &nbsp; return render_template('event.html', event=e)&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; return f'Event {event} not found', 404

慕妹3146593

这可以使用自定义 URL 转换器并提供序列化类的方法,这很快就会变得乏味:from __future__ import annotationsimport jsonclass Event():    def __init__(self, name, date):        self.name = name        self.date = date    def to_url(self):        name = self.name.replace(' ', '+')        # format the date similarly        return f'name+{name}+date+{self.date}'    @classmethod    def from_url(cls, url: str):        # extract name and date from url ...        event = Event(name, date)然后,您可以按如下方式编写转换器:from werkzeug.routing import BaseConverterfrom app.models.event import Eventclass EventConverter(BaseConverter):    def to_python(self, url):        return Event.from_url(url)    def to_url(self, event):        return event.to_url()然后在创建应用程序时使用以下方法声明它:from app.converters.event_converter import EventConverter# etc.app.url_map.converters['event'] = EventConverter # add URL converters.并将其用于您的路线,例如:@app.route('/event/<event:event>')def event(event):    pass请注意,这很好,我之前曾将它用于较小的项目,您可以将其仅存储在内存中,但您最好使用 ID 并将事件存储在数据库中。因此,假设您有一个应用程序工厂:from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()def create_app():    app = Flask(__name__)    db.init_app(app)    # etc.您将访问数据库并定义一个模型,如下所示:from app import dbclass Event(db.Model)    id = db.Column(db.Integer, primary_key=True)    name = db.Column(db.String, nullable=False)    date = db.Column(db.DateTime, nullable=False)后您可以按如下方式查询表/模型:Eventfrom app.models.event import Event@app.route('/event/<int:event_id>')def event(event_id):    event = Event.query.get(event_id)    # etc.
随时随地看视频慕课网APP

相关分类

Html5
我要回答