zoukankan      html  css  js  c++  java
  • 让django像Asp.Net Mvc一样自动匹配Controller和Action

    Asp.Net Mvc 中,我们可以通过配置如下路由,允许从Url中匹配每段路径到Area, Controller和Action中,在尝试使用了django之后,发现django的路由系统更加灵活,允许通过正则匹配任意Url到任意View,但如果希望通过在Url路径中指定要访问的app, view,就比较麻烦,我下面的尝试,通过匹配Url,使用python自省(反射)查找特定View方法并返回该方法执行结果,建立了一个简单的python路由规则。

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
    
    }

    代码列表-1 Asp.Net Mvc路由配置

    为了不影响现有逻辑,我在原django项目中新建了一个routed app,在该app中配置路由,下面是django项目结构

    DjangoApp
      |-urls.py
      |-settings.py
      |-manage.py
      |-views.py
      |-routed
          |-urls.py
          |-models.py
          |-tests.py
    

    代码列表-2 django项目结构

    首先需要改动的是项目的根urls.py,凡是所有以"routed"开头的url,都交给routedapp下的urls.py来处理

    (r'^routed/', include('DjangoApp.routed.urls')),
    

    代码列表-3 项目根urls.py的更改

    然后,在routed app的urls.py中,添加对url按照路由进行解析的规则

    from django.conf.urls.defaults import *
    from DjangoApp.routed.viewstart import start
    
    urlpatterns = patterns('',
    	(r'^(?P<controller>\w+)?/(?P<action>\w+)?/(?P<parameter>.+)?$', start),
    )
    

    代码列表-4 routed app中urls.py的更改

    在这个规则中,将所有类似"/routed/controllerabc/actionxyz/parm123"的url都指向viewstart.py中的start方法处理

    import inspect
    from util.response import *
    from util.common import *
    
    
    def start(request,controller,action,parameter):
    	#initialize controller, execute action with parameter
    	prefix = 'DjangoApp.routed.controllers.'
    
    	namespace = prefix + controller
    	__import__(namespace)
    	module = common.importmodule(namespace)
    	
    	methods = [k for k,v in inspect.getmembers(module) if k == action]
    	if len(methods) <= 0:
    		return response.http404()
    
    	return getattr(module,methods[0])(request)
    

    代码列表-5 viewstart.py

    在viewstart.py中,根据匹配得到的Controller查找python模块,然后过滤用inspect.getmembers得到的方法,找到对应Action并执行之,python中的反射非常易用,内置方法__import__可动态引入需要的模块,globals方法可以返回传入的字符串代表的对象,getattr方法的返回值直接加上括号即可执行。代码中,util.common中封装了由字符串反射得到对象实例的方法,util.response封装了各种http response的方法,参考代码列表-6、代码列表-7。

    import os
    import sys
    
    class common:
        @classmethod
        def importmodule(self,namespace):
            components = namespace.split('.')
            if len(components) == 1:
                return globals()[namespace]
    
            module = __import__(components[0])
            for compent in components[1:]:
                module = getattr(module, compent)
    
            return module
    

    代码列表-6 common.py

    from django.template import Context
    from django.template.loader import get_template
    from django.shortcuts import render_to_response
    from django.http import HttpResponse
    from django.core import serializers 
    
    
    class response:
    	@classmethod
    	def json(self,object):
    		json = serializers.serialize("json", object)
    		return HttpResponse(json,'application/json')
    
    	@classmethod
    	def xml(self,object):
    		xml = serializers.serialize("xml", object)
    		return HttpResponse(xml,'application/xml')
    	
    	@classmethod
    	def falt(self,errormessage=''):
    		return self.json({"errorcode":"500","message":errormessage if errormessage else ''})
    
    	@classmethod
    	def view(self,view,view_model=None):
    		view_path = view+'.view'
    		return render_to_response(view_path,view_model)
    
    	@classmethod
    	def text(self,text):
    		return HttpResponse(text)
    
    	@classmethod
    	def http404(self):
    		return self.view('http404')

    代码列表-7 response.py

    最后,我们只要在routed app下创建controllers文件夹,然后创建controller即可通过controller名称对应的Url访问,如创建book.py

    from util.response import *
    from routed.models import Book
    
    def list(request):
    	books = Book.objects.all()
    	return response.json(books)
    

    代码列表-8 book.py

    输入book controller中的list action对应的url http://localhost/routed/book/list 试试看吧。

  • 相关阅读:
    122. 买卖股票的最佳时机 II
    45. 跳跃游戏 II
    134. 加油站
    55. 跳跃游戏
    714. 买卖股票的最佳时机含手续费
    121. 买卖股票的最佳时机
    860. 柠檬水找零
    开发环境安装合集(部分搬运)
    javascript的单例模式
    javascript 工厂模式
  • 原文地址:https://www.cnblogs.com/windvoice/p/2535020.html
Copyright © 2011-2022 走看看