在金贾2和烧瓶之间传递自定义蟒蛇对象

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


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对象传递到视图中是如此简单时,似乎可能有一种同样简单的方法可以将其从视图中取回。请启发我!


牧羊人nacy
浏览 94回答 3
3回答

aluckdog

@app.route('/event/<event>')<event>,在本例中为字符串。有关此内容的详细信息,请参阅 Flask 快速入门。您不能像在这里尝试的那样通过URL传递任意对象。通常,您在此处会有某种类型的 ID,可用于查找对象,可能是在数据库中。在这种情况下,您将该 ID 传递到该 ID 中,该 ID 将生成一个类似于 的 URL。url_for()/events/123然后,当您的路由被调用时,会在参数中为其指定 ID。然后,由您查找正确的对象并将其传递到模板中。eventevent

翻过高山走不出你

当您收到时,, 只是一个字符串,而不是一个对象。因此,您应该在数据库中找到事件 ID,例如<event>@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

慕侠2389804

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