添加slugified标题到网址

时间:2014-10-19 13:20:52

标签: python flask

我有一个类似/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)

但我怎么把它放在网址中?

1 个答案:

答案 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步骤。