用文章的标题创建一个网址 [英] Create a url with an article's title

查看:246
本文介绍了用文章的标题创建一个网址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MongoDB中有文章。我希望文章的网址可读。如果我有一篇名为如何在Heroku中无缝使用Flask和MongoDB的文章,我想要的URL是 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆