Django - 查看,网址古怪

时间:2011-01-24 18:25:25

标签: python django django-urls

我注意到Django处理我的url模式的一个奇怪的行为。用户应该登录,然后重定向到他们的个人资料页面。我还可以让用户编辑他们的个人资料。

以下是我的某个应用的网址格式:

urlpatterns=patterns('student.views',
    (r'profile/$', login_required(profile,'student')),
    (r'editprofile/$', login_required(editprofile,'student')),
)

这适用于名为student的应用。如果用户转到/ student / profile,他们应该获取配置文件视图。如果他们转到/ student / editprofile,他们应该获得editprofile视图。我设置了一个名为login_required的函数,它对用户进行了一些检查。这比我只能用注释处理的要复杂一点。

这是login_required:

def login_required(view,user_type='common'):
    print 'Going to '+str(view)
    def new_view(request,*args,**kwargs):
        if(user_type == 'common'):
            perm = ''
        else:
            perm = user_type+'.is_'+user_type
        if not request.user.is_authenticated():
            messages.error(request,'You must be logged in.  Please log in.')
            return HttpResponseRedirect('/')
        elif request.user.is_authenticated() and user_type != 'common' and not request.user.has_perm(perm):
            messages.error(request,'You must be an '+user_type+' to visit this page.  Please log in.')
            return HttpResponseRedirect('/')
        return view(request,*args,**kwargs)
    return new_view

无论如何,奇怪的是,当我访问/ student / profile时,即使我到了正确的页面,login_required也会打印出以下内容:

Going to <function profile at 0x03015DF0>
Going to <function editprofile at 0x03015BB0>

为什么同时打印?为什么要试图访问这两个?

即使更奇怪,当我尝试访问/ student / editprofile时,个人资料页面会加载,这就是打印的内容:

Going to <function profile at 0x02FCA370>
Going to <function editprofile at 0x02FCA3F0>
Going to <function view_profile at 0x02FCA4F0>

view_profile是一个完全不同的应用程序中的函数。

3 个答案:

答案 0 :(得分:2)

这两种模式:

(r'profile/$', login_required(profile,'student')),
(r'editprofile/$', login_required(editprofile,'student')),

两者都匹配http://your-site/student/editprofile

尝试:

(r'^profile/$', login_required(profile,'student')),
(r'^editprofile/$', login_required(editprofile,'student')),

Django首先使用视图匹配模式(see number 3 here)。

答案 1 :(得分:2)

不确定为什么你不能使用标准的@login_required装饰器 - 看来你的版本实际上提供了 less 功能,因为它总是重定向到\,而不是实际登录视图。

在任何情况下,打印两者的原因是因为print语句位于装饰器的顶层,因此在urlconf 评估时执行。如果将它放在内部new_view函数中,它只会在实际调用时执行,并且只应打印相关的视图名称。

答案 2 :(得分:1)

你的login_required看起来像是一个蟒蛇装饰者。您需要在urls.py中使用它的任何原因吗?

我认为在读取print 'Going to '+str(view)时评估urlpatterns行以确定要执行的视图。它看起来很奇怪,但我认为它不会伤害你。

每次点击视图时都不会执行行print 'Going to '+str(view),只有在评估了网址模式时(我认为)。 new_view中的代码是唯一将作为视图的一部分执行的代码。