Django视为类

时间:2013-10-16 02:50:17

标签: python django

我做了一些谷歌搜索,实际上找不到答案。

假设我有以下简单类:

class dashboard:
    def index(self, request):
        return HttpResponse("Hello world")

    def profile(self, request):
        return HttpResponse("Your profile")

    def user(self, request, user_id):
        usr = User.objects.get(id=user_id)
        return HttpResponse("Some info on usr")

我想要做的是映射:

mysite.com/dashboard => dashboard.index

mysite.com/dashboard/profile => dashboard.profile

mysite.com/dashboard/user/1 => dashboard.user(1)

无需为每个网址设置网址格式 - 例如:

urlpatterns = patterns('',
    url(r'^/dashboard$', views.dashboard, name='dashboard'),
    url(r'^/dashboard/profile$', views.profile, name='profile'),
    # etc...
)

我想到了这一点,我能想到的唯一可行的是:

urlpatterns = patterns('',
    url(r'^/(?<root1>\w+)/(?<root2>\w+)/(?<root3>)$', urltrigger, name='trigger'),
    # etc...
)

# https://stackoverflow.com/questions/547829/how-to-dynamically-load-a-python-class
def my_import(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

def urltrigger(request, root1, root2 = None, root3 = None):
    try:
        cmodule = my_import(root1)
        dync = cmodule() # perhaps request is a parameter to the constructor?
        if root2 = None:
            dync.index(request)
        else:
            method = getattr(dync, root2)
            if root3 == None:
                method()
            else:
                method(root3)
    except:
        raise Http404

(请原谅快速完成的Python代码)这真的不应该引入任何安全问题,因为类模块必须存在于pythonpath中 - 如果攻击者确实可以访问pythonpath中的文件,他们就可以轻松地修改其他视图/代码。

有没有人对此有任何想法?使用这种方法我可能会失去使用Django装饰器的能力 - 我可以使用它,因为我可以模仿我想要的装饰器的行为(例如确保一个人登录和/或在特定组中)班级的构造者。

编辑:

我完成了所有工作 - 它只有10行代码。

EDIT2:

对于那些想知道:

将此作为模式:

(r'^(.+?)/(?:(.+?)/)?$', free_pattern)

这里是free_pattern(我从那时起就明显修改了它):

def free_pattern(request, view, segments=""):
    if segments != None:
        segments = segments.split(r'/')

    match = re.match("(\.|\\|/)", view)
    if match:
        raise Http404

    dnyc = None
    try:
        if not segments:

            cmodule = __import__(view + ".controllers." + view, globals(), locals(), [view], -1)
            dnyc = getattr(cmodule, view)

        else:
            cmodule = __import__(view + ".controllers." + segments[0], globals(), locals(), [segments[0]], -1)
            dnyc = getattr(cmodule, segments[0])
    except Exception, e:
        return HttpResponse(str(e))

    c = dnyc(request)
    if segments == None or len(segments) == 1:
        return c.index()
    else:
        lst = segments[2:]
        return getattr(c, segments[1])(*lst)

如果你去/ site /它会在site / controllers / site.py中加载类站点并调用索引方法:

class site:
    def __init__(self, request):
        pass # do something with request
    def index(self):
        pass

如果你去/ site / page它将加载site / controllers / page.py中的类页面并调用index方法。转到/ site / page / one会调用类页面中的一个方法,最后转到/ site / page / one / 1 /会将1(及其后的任何内容)作为参数传递给方法。< / p>

如果你认为这不会起作用 - 告诉我为什么,而不是“我真的很高兴我永远不会支持这一点”。后者没有帮助我,没有帮助其他人,也没有解释为什么这样的系统不起作用。在我看来 - 仅凭评论不会回答这个问题。

如果你想知道我被困在Django 1.4上,因为我必须使用没有virtualenv / pip / easy_install的Python 2.5。我真的很想 - 但这是不容谈判的。这不仅仅是因为我的“个人”使用 - 所以切换网络主机也是不可能的。

我要注意的一件事 - 使用官方Django CBV只会引入相同的问题(忽略安全性) - 例如无法应用Django装饰器,例如login_requried。人们可以看到这篇SO帖子(https://stackoverflow.com/a/11525851/195722)来解决这个问题。

0 个答案:

没有答案