【问题标题】:Create a url with an article's title创建带有文章标题的 url
【发布时间】:2015-01-03 22:40:11
【问题描述】:

我在 MongoDB 中有文章。我希望文章的 URL 可读。如果我有一篇名为“如何通过 Heroku 无缝使用 Flask 和 MongoDB”的文章,我希望 URL 类似于 localhost:5000/blog/how-to-use-flask-and-mongodb-seamlessly-with-heroku

完成此任务的最佳方法是什么?任何指向正确方向的指针都值得赞赏。我不确定从哪里开始。

【问题讨论】:

    标签: python url flask seo


    【解决方案1】:

    您正在寻找一种方法来生成“slug”并使用它来识别帖子。

    如果您只想使用 slug,则所有帖子标题都必须有一个唯一的 slug(这大约意味着一个唯一的标题)。这也意味着,如果您更改帖子的标题,则 url 可能会更改,这会使书签和其他外部链接失效。

    更好的方法是像 Stack Overflow 对问题所做的那样。如果您查看此问题的 URL,您会注意到它有一个唯一的 id 和一个 slug。事实上,slug 是可选的,你仍然可以通过从 url 中删除它来访问此页面。

    您需要一种生成 slug 的方法,以及一个自定义的 url converterinflection 库提供了一种使用 parameterize 方法对字符串进行 slugify 的好方法。下面的 url 转换器接受一个对象并返回一个带有 the_object.idthe_object.title 作为 slug 的 url。解析 url 时,它只会返回对象的 id,因为 slug 是可选的。

    from inflection import parameterize
    from werkzeug.routing import BaseConverter
    
    class IDSlugConverter(BaseConverter):
        """Matches an int id and optional slug, separated by "/".
    
        :param attr: name of field to slugify, or None for default of str(instance)
        :param length: max length of slug when building url
        """
    
        regex = r'-?\d+(?:/[\w\-]*)?'
    
        def __init__(self, map, attr='title', length=80):
            self.attr = attr
            self.length = int(length)
            super(IDSlugConverter, self).__init__(map)
    
        def to_python(self, value):
            id, slug = (value.split('/') + [None])[:2]
            return int(id)
    
        def to_url(self, value):
            raw = str(value) if self.attr is None else getattr(value, self.attr, '')
            slug = parameterize(raw)[:self.length].rstrip('-')
            return '{}/{}'.format(value.id, slug).rstrip('/')
    

    注册转换器以便它可以在路由中使用:

    app.url_map.converters['id_slug'] = IDSlugConverter
    

    在路线中使用它:

    @app.route('/blog/<id_slug:id>')
    def blog_post(id):
        # get post by id, do stuff
    

    为帖子生成一个网址。请注意,您将对象('post'),而不仅仅是 id,传递给 id 参数。:

    url_for('blog_post', id=post)
    # /blog/1234/the-post-title
    

    我为 Stack Overflow Python 聊天室 site 编写的转换器。

    【讨论】:

      猜你喜欢
      • 2013-01-17
      • 1970-01-01
      • 2013-12-04
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多