【问题标题】:Django - view, url weirdnessDjango - 查看,网址怪异
【发布时间】:2011-06-14 17:03:13
【问题描述】:

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

这是我的一个应用程序的 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 是一个完全不同的应用程序中的函数。

【问题讨论】:

  • decorators.login_required() 和 decorators.permission_required() 有什么让人难以忍受的地方??

标签: python django django-urls


【解决方案1】:

这两种模式:

(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)。

【讨论】:

  • 这就是问题所在。我认为因为这个 urls.py 被包含在另一个 urls.py 中,所以我不会在前面使用“^”,但事实证明我需要。谢谢!
【解决方案2】:

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

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

【讨论】:

  • 您对 print 语句的看法是正确的,但是为什么仍然为 editprofile 返回错误的视图
【解决方案3】:

您的login_required 看起来像是一个python 装饰器。有什么理由需要在 urls.py 中包含它?

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

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

【讨论】:

  • 也许我可以把它用作装饰器。但即使如此......好吧,你是对的 new_view 只是被执行,但是为什么当我尝试 editprofile 时会加载错误的视图
猜你喜欢
  • 2011-05-02
  • 2014-07-21
  • 2016-04-10
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 2020-12-26
  • 2019-08-25
  • 1970-01-01
相关资源
最近更新 更多