使用文章标题创建 url
Create a url with an article's title
我在 MongoDB 中有文章。我希望文章的 URLs 易于阅读。如果我有一篇名为 "How to Use Flask and MongoDB Seamlessly with Heroku" 的文章,我希望 URL 类似于 localhost:5000/blog/how-to-use-flask-and-mongodb-seamlessly-with-heroku
.
完成此任务的最佳方法是什么?对正确方向的任何指示表示赞赏。我不确定从哪里开始。
您正在寻找一种方法来生成 "slug" 并使用它来识别 post。
如果您只想使用 slug,所有 post 标题都必须有一个独特的 slug(这大约意味着一个独特的标题)。这也意味着如果您更改 post 的标题,url 可能会更改,这会使书签和其他外部链接失效。
更好的方法是像 Stack Overflow 那样做一些问题。如果您查看此问题的 URL,您会注意到它有一个唯一的 ID 和一个 slug。事实上,slug 是可选的,您仍然可以通过从 url.
中删除它来访问此页面
您需要一种生成 slug 的方法,以及一种自定义 url converter. The inflection library provides a nice way to slugify strings with the parameterize
方法。以下 url 转换器将 object 和 return 与 url 以及 the_object.id
和 the_object.title
作为 slug。解析 url 时,它只会 return object 的 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 生成 url。请注意,您将 object ('post') 而不仅仅是 id 传递给 id 参数。:
url_for('blog_post', id=post)
# /blog/1234/the-post-title
我为 Stack Overflow Python 聊天室编写的转换器 site。
我在 MongoDB 中有文章。我希望文章的 URLs 易于阅读。如果我有一篇名为 "How to Use Flask and MongoDB Seamlessly with Heroku" 的文章,我希望 URL 类似于 localhost:5000/blog/how-to-use-flask-and-mongodb-seamlessly-with-heroku
.
完成此任务的最佳方法是什么?对正确方向的任何指示表示赞赏。我不确定从哪里开始。
您正在寻找一种方法来生成 "slug" 并使用它来识别 post。
如果您只想使用 slug,所有 post 标题都必须有一个独特的 slug(这大约意味着一个独特的标题)。这也意味着如果您更改 post 的标题,url 可能会更改,这会使书签和其他外部链接失效。
更好的方法是像 Stack Overflow 那样做一些问题。如果您查看此问题的 URL,您会注意到它有一个唯一的 ID 和一个 slug。事实上,slug 是可选的,您仍然可以通过从 url.
中删除它来访问此页面您需要一种生成 slug 的方法,以及一种自定义 url converter. The inflection library provides a nice way to slugify strings with the parameterize
方法。以下 url 转换器将 object 和 return 与 url 以及 the_object.id
和 the_object.title
作为 slug。解析 url 时,它只会 return object 的 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 生成 url。请注意,您将 object ('post') 而不仅仅是 id 传递给 id 参数。:
url_for('blog_post', id=post)
# /blog/1234/the-post-title
我为 Stack Overflow Python 聊天室编写的转换器 site。