【问题标题】:how do you slugify a url?你如何 slugify 一个网址?
【发布时间】:2017-03-20 08:29:36
【问题描述】:

我正在使用 slugify,但我不知道如何使我的帖子标题 slugified,我需要在我的帖子中创建一个新列吗?我整天都被困在这上面。

有什么建议吗?

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

错误信息

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

【问题讨论】:

  • 尝试登录title。收到了吗?
  • 该错误仅表示它找不到任何行,而您期望一行。我通常使用Post.query.filter_by(title=title).first()之类的东西,然后检查结果是否为空。
  • @btquanto 你能改一下我不明白的说法吗?
  • Post.query.filter_by(title=title).first() 有效,但是当我将 slugify 放在上面时它不起作用
  • 我假设您使用的是url_for('show', title=title)。这不起作用,因为您没有通过标题,而是通过了蛞蝓。当您查询数据库时,没有标题与 slug 匹配。如果您需要通过 slug 查询,那么是的,您应该将其存储在您的数据库中。

标签: python flask slug


【解决方案1】:

您在视图中使用slug 而不是title,并基于slug 查询数据库。在创建帖子时,您将 slugify 标题并将其存储在 slug 字段中。

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)

请注意,我们在这里使用.first 而不是.one,因为如果没有找到帖子,.first 将返回None,而.one 会引发一个异常,您需要根据它捕获并进行流程。

如果没有找到帖子,那么我们将返回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)

【讨论】:

  • 非常感谢 vivek,我想指出我使用 slug = db.Column(db.String(80)) 但我没有添加 index = true 属性,当我之前尝试过时,谢谢你解释它的方式很有意义。但是,我不断收到此错误 sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: posts.slug [SQL: 'SELECT posts.id AS posts_id, posts.title AS posts_title, posts.body AS posts_body, posts。 slug AS posts_slug \nFROM posts'] Traceback(最近一次调用最后一次)
  • @EliHood 我认为您尚未在您的帖子数据库表中创建列slug。您可以手动在数据库中插入列,或者如果您使用的是flask-sqlalchemy,那么您可以使用db.create_all() 创建表。
  • 它现在可以工作了,我所做的是使用了不同的 sql 数据库名称,而不是 test.db,我使用了 test12.db,这是您在 __init__ 文件中识别您的数据库名称的地方,就像这个 app.config ['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join( tempfile.gettempdir(), 'test122.db') 但仍然想知道如何彻底清除数据库
【解决方案2】:

我的猜测是您正在为帖子使用诸如“这是我的第一篇博文”之类的标题,这很棒。我还猜想您想使用 slug 以便为每个帖子提供更 URL 友好的永久链接。在前一种情况下,slug 类似于“this-is-my-first-blog-post”

因此,给定一个 slug,您的帖子将在 /posts/{unique-post-slug} 路由而不是 /posts/{title} 上可用。我的建议是将 slug 存储在数据库中以便检索帖子,因为反向 slugify 并不那么容易。

总结一下你的模型应该是:

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)

注意index=True 选项。这样做是为了加快查询速度。

应该呈现您的帖子的路线是

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

在您的 post.html 文件中,您可以将所有帖子字段(id、title、body、slug)用作 post.id、post.title 等

【讨论】:

  • db.Text 用于存储多行文本,您可以使用db.string
猜你喜欢
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
相关资源
最近更新 更多