我有一个类似/posts/1
的网址,其中1表示数据库中文章的ID。
@bp.route('/<post_id>')
@login_required
def post(post_id):
""" find the post and then show it """
p = Post.query.get(post_id)
return render_template("post/single_post.html", post=p)
然而,我想要做的是有一个带有某种标题的网址,例如/posts/1/my_stack_overflow_question_is_bad
。我可以在模型中制作一个slugify属性:
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String)
html = db.Column(db.String)
@property
def slugified_title():
return slugify(self.title, separator="_", to_lower=True)
但我怎么把它放在网址中?
答案 0 :(得分:6)
您只需要将slug元素添加到URL路由:
@bp.route('/<post_id>/<slug>')
@login_required
def post(post_id, slug):
""" find the post and then show it """
p = Post.query.get(post_id)
return render_template("post/single_post.html", post=p)
然后当你想为它创建URL时 - 只需将slug提供给url_for
函数:
p = Post.query.get(1)
url_for('post', post_id=p.id, slug=p.slugified_title)
这可能会有点乏味,所以我倾向于permalink decorator:
# Taken from http://flask.pocoo.org/snippets/6/
from flask import url_for
from werkzeug.routing import BuildError
def permalink(function):
def inner(*args, **kwargs):
endpoint, values = function(*args, **kwargs)
try:
return url_for(endpoint, **values)
except BuildError:
return
return inner
然后调整我的模型使用它:
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String)
html = db.Column(db.String)
@property
def slugified_title():
return slugify(self.title, separator="_", to_lower=True)
@permalink
def url(self):
# where 'post' is the title of your route that displays the post
return 'post', {'post_id': self.id, 'slug':self.slugified_title}
这样当我需要一个网址时,我可以直接询问该对象的网址,而不必手动浏览url_for步骤。