2014-10-19 35 views
2

我有一個像/posts/1這樣的網址,其中1表示db中文章的ID。爲網址添加slugified標題

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

不過,我想這樣做是有一個網址,在它某種slugified稱號,像/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) 

但我將如何把它在網址?

回答

6

你只需要蛞蝓元素添加到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_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,而不必手動經過url_for一步。

+0

優秀的答案,謝謝你超越和超越 – corvid 2014-10-19 15:47:04