为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

哈士奇WWW 2023-12-11 15:28:48
我是 Flask、Jinja2 和 HTML 模板的新手,我正在尝试学习如何在控制器和视图之间来回传递信息。基本上,我有一个事件日历。每个事件名称都是一个超链接,用于url_for转至包含有关该事件的更多信息的视图。但是,尽管我可以轻松地将自定义事件对象列表传递到 HTML 文件中,但我不知道如何将选定的事件对象返回到控制器。据我所知,该对象正在变成一个字符串。下面的简化代码。app.pyfrom flask import Flask, render_template, url_forapp = Flask(__name__)class Event(object):    def __init__(self, name, date):        self.name = name        self.date = dateevents = [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 对象传递到视图中如此简单时,似乎有一种同样简单的方法可以将其从视图中返回。请赐教!
查看完整描述

3 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

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

<event>,在本例中,是一个字符串。

通常,您会在此处拥有某种 ID,可用于查找对象(可能在数据库中)。在这种情况下,您可以将该 ID 传递到其中url_for(),从而生成类似 的 URL /events/123

然后,当您的event路由被调用时,它会在参数中获得 ID event。然后由您来查找正确的对象并将其传递到您的模板中。


查看完整回答
反对 回复 2023-12-11
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

当您收到<event>, 只是一个字符串,而不是一个对象。所以你应该在你的数据库中找到事件ID,比如


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

def event(event):

    e=db.find_event(event) # event is the event number or id 

    if e:

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

    else:

        return f'Event {event} not found', 404


查看完整回答
反对 回复 2023-12-11
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

这可以使用自定义 URL 转换器并提供序列化类的方法,这很快就会变得乏味:


from __future__ import annotations

import json


class 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 BaseConverter

from app.models.event import Event


class 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 SQLAlchemy

db = SQLAlchemy()

def create_app():

    app = Flask(__name__)

    db.init_app(app)

    # etc.

您将访问数据库并定义一个模型,如下所示:


from app import db


class 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)

后您可以按如下方式查询表/模型:Event


from app.models.event import Event


@app.route('/event/<int:event_id>')

def event(event_id):

    event = Event.query.get(event_id)

    # etc.


查看完整回答
反对 回复 2023-12-11
  • 3 回答
  • 0 关注
  • 77 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信