Python Routes map.resource详解
来源:互联网 发布:电信4g网络接入点设置 编辑:程序博客网 时间:2024/06/05 04:51
文档参考:
http://routes.readthedocs.org/en/latest/introduction.html
demo参考:
http://blog.csdn.net/bellwhl/article/details/8956088
#!/usr/bin/env/python#coding=utf-8from routes import Mapperfrom routes import middlewareimport webob.decfrom wsgiref.simple_server import make_serverclass controller(object): def __init__(self): self.i = 1 def __call__(self): print self.i def search(self): return "do search()" def show(self): return "do show()" def index(self): return "do index()" def update(self): return "do update()" def delete(self): return "do delete()" def create(self): return "do create()" def create_many(self): return "do create_many()" def update_many(self): return "do update_many()" def list_many(self): return "do list_many()" def delete_many(self): return "do delete_many()" def preview(self): return "do preview()"class appclass(object): def __init__(self): a = controller() map = Mapper() map.resource('message', 'messages', controller=a, path_prefix='/{projectid}', name_prefix='lala_', collection={'list_many': 'GET', 'create_many': 'POST'}, member={'update_many': 'POST', 'delete_many': 'POST'}, new={'preview' : 'POST'}, parent_resource=dict(member_name="haha", collection_name="heihei")) self.route = middleware.RoutesMiddleware(self.dispatch, map) @webob.dec.wsgify def __call__(self, req): return self.route @staticmethod @webob.dec.wsgify def dispatch(req): match = req.environ['wsgiorg.routing_args'][1] route = req.environ['routes.route'] print "route match result is:", match if not match: return "fake url" print "route.name: %s, route.routepath: %s, route.conditions: %s" % (route.name, route.routepath, route.conditions) controller = match['controller'] action = match['action'] if hasattr(controller, action): func = getattr(controller, action) ret = func() return ret else: return "has no action:%s" % actionif __name__ == "__main__": app = appclass() server = make_server('', 8088, app) server.serve_forever()
1. GET http://127.0.0.1:8088/project_id_value/messages
do index()
route match result is: {'action': u'index', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>}
route.name: lala_messages, route.routepath: /{projectid}/messages, route.conditions: {'method': ['GET']}
2. POST http://127.0.0.1:8088/project_id_value/messages
do create()
route match result is: {'action': u'create', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>}
route.name: None, route.routepath: /{projectid}/messages, route.conditions: {'method': ['POST']}
3. PUT http://127.0.0.1:8088/project_id_value/messages/1
do update()
route match result is: {'action': u'update', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>, 'id': u'1'}
route.name: None, route.routepath: /{projectid}/messages/:(id), route.conditions: {'method': ['PUT']}
4. DELETE http://127.0.0.1:8088/project_id_value/messages/1
do delete()
route match result is: {'action': u'delete', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>, 'id': u'1'}
route.name: None, route.routepath: /{projectid}/messages/:(id), route.conditions: {'method': ['DELETE']}
5. GET http://127.0.0.1:8088/project_id_value/messages/1
do show()
route match result is: {'action': u'show', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>, 'id': u'1'}
route.name: lala_message, route.routepath: /{projectid}/messages/:(id), route.conditions: {'method': ['GET']}
6. POST http://127.0.0.1:8088/project_id_value/messages/new/preview
do preview()
route match result is: {'action': u'preview', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>}
route.name: lala_preview_new_message, route.routepath: /{projectid}/messages/new/preview, route.conditions: {'method': ['POST']}
7. GET http://127.0.0.1:8088/project_id_value/messages/list_many
do list_many()
route match result is: {'action': u'list_many', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>}
route.name: lala_list_many_messages, route.routepath: /{projectid}/messages/list_many, route.conditions: {'method': ['GET']}
8. POST http://127.0.0.1:8088/project_id_value/messages/create_many
do create_many()
route match result is: {'action': u'create_many', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>}
route.name: lala_create_many_messages, route.routepath: /{projectid}/messages/create_many, route.conditions: {'method': ['POST']}
9. POST http://127.0.0.1:8088/project_id_value/messages/1/update_many
do update_many()
route match result is: {'action': u'update_many', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>, 'id': u'1'}
route.name: lala_update_many_message, route.routepath: /{projectid}/messages/:(id)/update_many, route.conditions: {'method': ['POST']}
10. POST http://127.0.0.1:8088/project_id_value/messages/1/delete_many
do delete_many()
route match result is: {'action': u'delete_many', 'projectid': u'project_id_value', 'controller': <__main__.controller object at 0x0000000002E570F0>, 'id': u'1'}
route.name: lala_delete_many_message, route.routepath: /{projectid}/messages/:(id)/delete_many, route.conditions: {'method': ['POST']}
注释掉path_prefix行,如下:
map.resource('message', 'messages', controller=a, # path_prefix='/{projectid}', name_prefix='lala_', collection={'list_many': 'GET', 'create_many': 'POST'}, member={'update_many': 'POST', 'delete_many': 'POST'}, new={'preview' : 'POST'}, parent_resource=dict(member_name="haha", collection_name="heihei"))
重启启动,注意route.name和route.routepath属性的变动:
1. GET http://127.0.0.1:8088/heihei/haha_value/messages
do index()
route match result is: {'action': u'index', 'controller': <__main__.controller object at 0x0000000002D7A0F0>, 'haha_id': u'haha_value'}
route.name: haha_messages, route.routepath: /heihei/:haha_id/messages, route.conditions: {'method': ['GET']}
2. POST http://127.0.0.1:8088/heihei/haha_value/messages/new/preview
do preview()
route match result is: {'action': u'preview', 'controller': <__main__.controller object at 0x0000000002D7A0F0>, 'haha_id': u'haha_value'}
route.name: haha_preview_new_message, route.routepath: /heihei/:haha_id/messages/new/preview, route.conditions: {'method': ['POST']}
3. GET http://127.0.0.1:8088/heihei/haha_value/messages/list_many
do list_many()
route match result is: {'action': u'list_many', 'controller': <__main__.controller object at 0x0000000002D7A0F0>, 'haha_id': u'haha_value'}
route.name: haha_list_many_messages, route.routepath: /heihei/:haha_id/messages/list_many, route.conditions: {'method': ['GET']}
...
map.resource源码:
<span style="font-size:12px;">def resource(self, member_name, collection_name, **kwargs): collection = kwargs.pop('collection', {}) member = kwargs.pop('member', {}) new = kwargs.pop('new', {}) path_prefix = kwargs.pop('path_prefix', None) name_prefix = kwargs.pop('name_prefix', None) parent_resource = kwargs.pop('parent_resource', None) # Generate ``path_prefix`` if ``path_prefix`` wasn't specified and # ``parent_resource`` was. Likewise for ``name_prefix``. Make sure # that ``path_prefix`` and ``name_prefix`` *always* take precedence if # they are specified--in particular, we need to be careful when they # are explicitly set to "". if parent_resource is not None: if path_prefix is None: path_prefix = '%s/:%s_id' % (parent_resource['collection_name'], parent_resource['member_name']) if name_prefix is None: name_prefix = '%s_' % parent_resource['member_name'] else: if path_prefix is None: path_prefix = '' if name_prefix is None: name_prefix = '' # Ensure the edit and new actions are in and GET member['edit'] = 'GET' new.update({'new': 'GET'}) # Make new dict's based off the old, except the old values become keys, # and the old keys become items in a list as the value def swap(dct, newdct): """Swap the keys and values in the dict, and uppercase the values from the dict during the swap.""" for key, val in dct.iteritems(): newdct.setdefault(val.upper(), []).append(key) return newdct collection_methods = swap(collection, {}) member_methods = swap(member, {}) new_methods = swap(new, {}) # Insert create, update, and destroy methods collection_methods.setdefault('POST', []).insert(0, 'create') member_methods.setdefault('PUT', []).insert(0, 'update') member_methods.setdefault('DELETE', []).insert(0, 'delete') # If there's a path prefix option, use it with the controller controller = strip_slashes(collection_name) path_prefix = strip_slashes(path_prefix) path_prefix = '/' + path_prefix if path_prefix and path_prefix != '/': path = path_prefix + '/' + controller else: path = '/' + controller collection_path = path new_path = path + "/new" member_path = path + "/:(id)" options = { 'controller': kwargs.get('controller', controller), '_member_name': member_name, '_collection_name': collection_name, '_parent_resource': parent_resource, '_filter': kwargs.get('_filter') } def requirements_for(meth): """Returns a new dict to be used for all route creation as the route options""" opts = options.copy() if method != 'any': opts['conditions'] = {'method':[meth.upper()]} return opts # Add the routes for handling collection methods for method, lst in collection_methods.iteritems(): primary = (method != 'GET' and lst.pop(0)) or None route_options = requirements_for(method) for action in lst: route_options['action'] = action route_name = "%s%s_%s" % (name_prefix, action, collection_name) self.connect("formatted_" + route_name, "%s/%s.:(format)" % \ (collection_path, action), **route_options) self.connect(route_name, "%s/%s" % (collection_path, action), **route_options) if primary: route_options['action'] = primary self.connect("%s.:(format)" % collection_path, **route_options) self.connect(collection_path, **route_options) # Specifically add in the built-in 'index' collection method and its # formatted version self.connect("formatted_" + name_prefix + collection_name, collection_path + ".:(format)", action='index', conditions={'method':['GET']}, **options) self.connect(name_prefix + collection_name, collection_path, action='index', conditions={'method':['GET']}, **options) # Add the routes that deal with new resource methods for method, lst in new_methods.iteritems(): route_options = requirements_for(method) for action in lst: path = (action == 'new' and new_path) or "%s/%s" % (new_path, action) name = "new_" + member_name if action != 'new': name = action + "_" + name route_options['action'] = action formatted_path = (action == 'new' and new_path + '.:(format)') or \ "%s/%s.:(format)" % (new_path, action) self.connect("formatted_" + name_prefix + name, formatted_path, **route_options) self.connect(name_prefix + name, path, **route_options) requirements_regexp = '[^\/]+(?<!\\\)' # Add the routes that deal with member methods of a resource for method, lst in member_methods.iteritems(): route_options = requirements_for(method) route_options['requirements'] = {'id':requirements_regexp} if method not in ['POST', 'GET', 'any']: primary = lst.pop(0) else: primary = None for action in lst: route_options['action'] = action self.connect("formatted_%s%s_%s" % (name_prefix, action, member_name), "%s/%s.:(format)" % (member_path, action), **route_options) self.connect("%s%s_%s" % (name_prefix, action, member_name), "%s/%s" % (member_path, action), **route_options) if primary: route_options['action'] = primary self.connect("%s.:(format)" % member_path, **route_options) self.connect(member_path, **route_options) # Specifically add the member 'show' method route_options = requirements_for('GET') route_options['action'] = 'show' route_options['requirements'] = {'id':requirements_regexp} self.connect("formatted_" + name_prefix + member_name, member_path + ".:(format)", **route_options) self.connect(name_prefix + member_name, member_path, **route_options)</span>
解释参数:
controller
Use the specified controller rather than deducing it from the collection name.
collection
Additional URLs to allow for the collection. Example:
member
Additional URLs to allow for a member. Example:
new
Additional URLs to allow for new-member functionality.
path_prefix
Prepend the specified prefix to all URL patterns. The prefix may include path variables. This is mainly used to nest resources within resources.
name_prefix
Prefix the specified string to all route names. This is most often combined with path_prefix to nest resources:
parent_resource
A dict containing information about the parent resource, for creating a nested resource. It should contain the member_name and collection_name of the parent resource. This dict will be available via the associated Route object which can be accessed during a request via request.environ["routes.route"].
If parent_resource is supplied and path_prefix isn’t, path_prefix will be generated from parent_resource as “<parent collection name>/:<parent member name>_id”.
If parent_resource is supplied and name_prefix isn’t, name_prefix will be generated from parent_resource as “<parent member name>_”.
- Python Routes map.resource详解
- Routes Resource
- python routes
- routes 详解
- Routes-openstack-python
- wsgi-restful-routes详解:
- wsgi-restful-routes详解
- Routes模块详解
- JFinal的Routes机制详解
- Routes
- Python的map()函数 详解
- python基础--map函数详解
- Python Resource
- Python Resource
- Python Resource
- 【详解】Python建立Map写Excel表
- Python中map和reduce详解
- MVC路由中routes.IgnoreRoute("{resource}.axd/{*pathInfo}") 到底什么意思!
- 使用Java控制UDP协议
- 使用原生ajax异步返回json数据
- mongodb索引
- Python:urllib 和urllib2之间的区别
- 帮助文档(3)
- Python Routes map.resource详解
- 【iOS开发-13】大神器:如何利用cocoapods使用第三方类库,以针对UISwitch的第三方类库为例
- 解决Informatica Powercenter IP地址改变后不能正常启动问题
- 算法导论-第7章 - 快速排序
- 多线程执行CPU过高问题
- 帮助文档(4)
- mysql
- 船舶爬虫出现过的问题
- MyEclipse优化设置(myeclipse突然卡死或卡住的问题及其他优化)