Reputation:
I'm using slugify, and I have no idea how to make my post title slugified, do I need to make a new column in my post? I've been stuck on this all day long.
Any suggestions ?
Views.py
@app.route('/posts/<title>')
@login_required
def show(title):
link = db.session.query(Post).filter_by(title = title).one()
link2 = slugify(link.title)
return render_template("post.html", post=link2, pid=id, title=link2)
Models.py
class Post(db.Model):
__tablename__ = "posts"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
def __init__(self, title, body):
self.title = title
self.body = body
error message
File "C:\Program Files\Python35-32\lib\site-packages\sqlalchemy\orm\query.py", line 2760, in one
raise orm_exc.NoResultFound("No row was found for one()")
sqlalchemy.orm.exc.NoResultFound: No row was found for one()
Upvotes: 0
Views: 3725
Reputation: 676
You take slug
instead of title
in your view and query database based on slug. While creating post you slugify
the title and store it in slug
field.
Views.py
@app.route('/posts/<slug>')
@login_required
def show(slug):
post = db.session.query(Post).filter_by(slug = slug).first()
if post:
return render_template("post.html", post=post)
abort(404)
Note that we are using .first
instead of .one
here because .first
return None
if no posts found whereas .one
raises an exception which you need to catch and make flow according to it.
If there is no post found then we are returning 404
.
Models.py
class Post(db.Model):
__tablename__ = "posts"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
slug = db.Column(db.String(80), index=True)
def __init__(self, title, body):
self.title = title
self.body = body
self.slug = slugify(title)
Upvotes: 2
Reputation: 1342
My guess is you are using a title for the posts such as "This is my first blog post" which is great. I am also guessing that you want to use the slug in order to have a more URL friendly permalink for each post. In the previous case the slug would be something like "this-is-my-first-blog-post"
So given a slug, your post would be available at the /posts/{unique-post-slug} route and not /posts/{title}. My suggestion would be to store the slug in the database in order to retrieve the post since reverse slugify isn't so easy.
To sum up your model should be:
class Post(db.Model):
__tablename__ = "posts"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
slug = db.Column(db.Text, index=True)
def __init__(self, title, body):
self.title = title
self.body = body
self.slug = slugfiy(title)
Notice the index=True
option. This is done for faster querying.
And the route that should render your post would be
@app.route('/posts/<slug>')
@login_required
def show(slug):
post = db.session.query(Post).filter_by(slug=slug).one()
return render_template("post.html", post=post)
In your post.html file you can use all the post fields (id, title, body, slug) as post.id, post.title, etc
Upvotes: 1