0

Recently I am trying to build a blog following Grinberg Miguel Flask mega tutorial. I got stocked when I try to slug my post title such that when it is clicked the detail will be displayed. This is my code:

(models.py)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(225))
    slug = db.Column(db.String(300))
    body = db.Column(db.Text)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)

def __repr__(self):
    return '<Post {}>'.format(self.body)

@staticmethod
def slugify (target, value, oldvalue, initiator):
    if value and (not target.slug or value != oldvalue):
        target.slug = slugify(value)
db.event.listen(Post.title, 'set', Post.slugify, retval=False)

my ROUTE code goes here:
from app.models import  Post

@bp.route('/', methods=['GET', 'POST'])
@bp.route('/index', methods=['GET', 'POST'])
def index():
    page = request.args.get('page', 1, type=int)
    posts = Post.query.order_by(Post.timestamp.desc()).paginate(
    page, current_app.config['POSTS_PER_PAGE'], False)
    next_url = url_for('main.explore', page=posts.next_num) \
    if posts.has_next else None
        prev_url = url_for('main.explore', page=posts.prev_num) \
    if posts.has_prev else None
return render_template('index.html', title=_('Home'),
                       posts=posts.items, next_url=next_url,
                       prev_url=prev_url)

@bp.route('/explore',methods=['GET', 'POST'])
@login_required
def explore():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(body=form.post.data, author=current_user)
        db.session.add(post)
        db.session.commit()
        flash(_('Your post is now live!'))
        return redirect(url_for('main.index'))
    return render_template('create.html', title=_('Create'),form=form)

@bp.route('/<slug>')
def detail(slug):
    posts = Post.query.order_by(Post.timestamp.desc()).paginate(
    page, current_app.config['POSTS_PER_PAGE'], False)
return render_template('detail.html', title=_('Home'),
                       posts=posts.items, next_url=next_url,
                       prev_url=prev_url)

I saw this error when I ran the code:

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: post.title [SQL: 'SELECT post.id AS post_id, post.title AS post_title, post.slug AS post_slug, post.body AS post_body, post.timestamp AS post_timestamp, post.user_id AS post_user_id

picciano
  • 22,341
  • 9
  • 69
  • 82
Mavis W L
  • 11
  • 2
  • Are you using Flask-Migrate to handle your database schema changes? The error is unrelated to the slug feature that you are working, SQLAlchemy is complaining that your `post` table does not have a `title` column. You have it defined in your model, so it seems you have not applied the corresponding changes to your database. – Miguel Grinberg Apr 20 '18 at 20:34
  • Yes I am using flask migrate. – Mavis W L Apr 21 '18 at 22:29
  • i have gone through the database migration upgrade. but got stocked index.html.{% for post in posts %}

    {{ post.title }}

    {{ post.body|safe }}

    {% include '_post.html' %} {% endfor %} also my detail.html: {% block app_content %} {{posts.title}} {{posts.body}} {% endblock %} and
    – Mavis W L Apr 22 '18 at 13:26
  • Sorry, but I don't understand what this new problem that you are having is about. Do you get any errors? – Miguel Grinberg Apr 22 '18 at 17:41
  • i got this: File "/root/ogahslab/app/templates/base.html", line 50, in block "content" {% block app_content %}{% endblock %} File "/root/ogahslab/app/templates/index.html", line 8, in block "app_content"

    {{ post.title }}

    File "/root/ogahslab/venv/lib/python3.6/site-packages/flask/helpers.py", line 333, in url_for return appctx.app.handle_url_build_error(error, endpoint, values) werkzeug.routing.BuildError: Could not build url for endpoint 'main.detail'. Did you forget to specify values ['slug']?
    – Mavis W L Apr 23 '18 at 20:45
  • The error is saying that you have a `url_for()` call for your `main.detail` route that is missing the slug argument. My guess is that you have at least one post object in your database that has `slug` set to `None`. – Miguel Grinberg Apr 24 '18 at 05:47
  • Looking at my post model above. Pls give me a clue on how resolve this. I am stranded – Mavis W L Apr 25 '18 at 09:30
  • It's not a problem with your model, it's the data that you have in the database that is incomplete. Make sure that all the posts that you have in the database have a slug set, or if you prefer, delete your database and start from scratch making sure all posts have slugs. – Miguel Grinberg Apr 26 '18 at 03:32
  • I got the content slugging instead of title. Where am I getting wrong – Mavis W L Apr 26 '18 at 17:02
  • thanks miguel i got it right after several debugging. just edited this line post = Post(body=form.post.data, title=form.title.data) in my explore route. thanks again for your time – Mavis W L Apr 26 '18 at 22:48

1 Answers1

0

Just ensure that the class name matches the table name . And the code should run fine

Arvin
  • 1
  • 1