I have a url like /posts/1
, where 1 refers to the id of the article in the db.
@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)
However, what I would like to do is have a url with some sort of slugified title in it, like /posts/1/my_stack_overflow_question_is_bad
. I can make a slugify property in the model:
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)
but how would I put that in the url?
You just need to add the slug element to the URL route:
@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)
Then when you want to create the URL for it-- just supply the slug into the url_for
function:
p = Post.query.get(1)
url_for('post', post_id=p.id, slug=p.slugified_title)
That can get a bit tedious, so I tend to have a permalink decorator:
# Inspired by http://flask.pocoo.org/snippets/6/
from flask import url_for
def permalink(function):
def inner(*args, **kwargs):
endpoint, values = function(*args, **kwargs)
return url_for(endpoint, **values)
return inner
Then adjust my model to use it:
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}
That way when I need a url, I can just ask the object for it's url, and not have to go through the url_for step manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With