2014-10-19 3 views
2

У меня есть URL-адрес, например /posts/1, где 1 обозначает идентификатор статьи в db.add slugified title to url

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

Однако то, что я хотел бы сделать, это иметь URL с какой-то 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) 

но как бы я положил это в URL-адрес?

ответ

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 для it-- просто поставить пробку в 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, и не должны проходить через url_for шаг вручную.

+0

Отличный ответ, спасибо за то, что выбрали выше и выше – corvid