用文章的标题创建一个网址 [英] Create a url with an article's title
问题描述
localhost:5000 / blog / how-to-use-flask-and-mongodb-无缝地与英雄
。 完成这个的最佳方法是什么?任何正确的方向指针赞赏。我不确定从哪里开始。
您正在寻找一种方法来生成slug并使用它来识别帖子。
如果你只想使用一个slu,,所有的帖子标题将必须有一个独特的slu((这大约意味着一个独特的标题) 。这也意味着,如果你改变帖子的标题,url可能会改变,这将使书签和其他外部链接无效。
更好的方法是做什么像堆栈溢出没有问题。如果你看这个问题的URL,你会注意到它有一个独特的ID和一个slu。。事实上,slug是可选的,你仍然可以通过从url中删除它来到这个页面。
你需要一种方法来生成slu,和一个自定义网址转换器。 变形库提供了一个很好的方式来使用 parameterize
方法。下面的URL转换器需要一个对象,并返回一个URL为 the_object.id
和 the_object.title
作为一个slug。当解析一个url时,它会直接返回对象的 id
,因为slug是可选的。
来自inflection从werkzeug.routing导入参数化
import BaseConverter
$ b $ class IDSlugConverter(BaseConverter):
匹配一个int id和可选的slug,
$ b:参数attr:slugify的字段名,或者缺省的str(实例)
:参数长度:构建url时的slu max最大长度
regex = r' - ?\ d +(?:/ [\ w\ - ] *)?'
def __init __(self, map,attr ='title',length = 80):
self.attr = attr
self.length = int(length)
super(IDSlugConverter,self).__ init __(map)
$ b $ def to_python(self,value):
id,slug =(value.split('/')+ [None])[:2]
return int(id)
$ b $ def to_url(self,value):
raw = str(value)if self.attr is None else getattr(value,self.att (raw)[:self.length] .rstrip(' - ')
return'{} / {}'。format(value.id,slug)。 rstrip('/')
注册转换器以便在路由中使用:
$ b $
app.url_map.converters ['id_slug'] = IDSlugConverter
在路线中使用它:
@ app.route('/ blog / < id_slug:id>')
def blog_post(id):
#通过ID获取帖子,做某事
生成帖子的网址。请注意,您将对象('post')(而不仅仅是id)传递给id参数:
url_for blog_post',id = post)
#/ blog / 1234 / the-post-title
由我为Stack Overflow编写的转换器Python聊天室 site 。
I have articles in MongoDB. I want the URLs for the articles to be readable. If I have an article named "How to Use Flask and MongoDB Seamlessly with Heroku", I want the URL to be something like localhost:5000/blog/how-to-use-flask-and-mongodb-seamlessly-with-heroku
.
What is the best way to accomplish this? Any pointers in the right direction are appreciated. I wasn't sure exactly where to start on this one.
You are looking for a way to generate a "slug" and use that to identify the post.
If you want to use just a slug, all post titles will have to have a unique slug (which approximately means a unique title). This also means that if you change the post's title, the url could change, which would invalidate bookmarks and other outside links.
A better method is to do something like what Stack Overflow does for questions. If you look at this question's URL, you'll notice it has a unique id and a slug. In fact, the slug is optional, you can still get to this page by removing it from the url.
You'll need a way to generate slugs, and a custom url converter. The inflection library provides a nice way to slugify strings with the parameterize
method. The following url converter takes an object and returns a url with the_object.id
and the_object.title
as a slug. When parsing a url, it will just return the object's id
, since the slug is optional.
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('/')
Register the converter so it can be used in routes:
app.url_map.converters['id_slug'] = IDSlugConverter
Use it in a route:
@app.route('/blog/<id_slug:id>')
def blog_post(id):
# get post by id, do stuff
Generate a url for a post. Note that you pass the object ('post'), not just the id, to the id parameter.:
url_for('blog_post', id=post)
# /blog/1234/the-post-title
Converter written by me for the Stack Overflow Python chat room site.
这篇关于用文章的标题创建一个网址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!