创建一个包含文章标题的网址

Dav*_* K. 3 python url seo flask

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

完成此任务的最佳方法是什么?任何指向正确方向的人都会受到赞赏.我不确定从这个开始的确切位置.

dav*_*ism 6

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

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

更好的方法是做类似Stack Overflow对问题的处理.如果你查看这个问题的URL,你会发现它有一个唯一的id和一个slug.实际上,slug是可选的,您仍然可以通过从URL中删除它来访问此页面.

你需要一种方法来生成slug和一个自定义url转换器.该拐点库提供了一个很好的方式slugify与字符串parameterize的方法.以下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('/')
Run Code Online (Sandbox Code Playgroud)

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

app.url_map.converters['id_slug'] = IDSlugConverter
Run Code Online (Sandbox Code Playgroud)

在路线中使用它:

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

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

url_for('blog_post', id=post)
# /blog/1234/the-post-title
Run Code Online (Sandbox Code Playgroud)

我为Stack Overflow Python聊天室网站编写的转换器.