Django - 视图、url 怪异
我注意到 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 是完全不同的应用程序中的函数。
I've noticed a strange behavior with how Django is processing my url patterns. A user should login and then be redirected to their profile page. I also have the ability for a user to edit their profile.
Here are my URL patterns for one of my apps:
urlpatterns=patterns('student.views',
(r'profile/
This is for an app called student. If the user goes to /student/profile they should get the profile view. If they go to /student/editprofile they should get the editprofile view. I setup a function called login_required which does some checks on the user. It's a little more complicated than I could handle with just annotations.
Here's 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
Anyways, the weird thing is that, when I visit /student/profile, even though I get to the right page, login_required prints the following:
Going to <function profile at 0x03015DF0>
Going to <function editprofile at 0x03015BB0>
Why is it printing both? Why is it trying to visit both?
Even weirder, when I try to visit /student/editprofile, the profile page is what loads and this is what's printed:
Going to <function profile at 0x02FCA370>
Going to <function editprofile at 0x02FCA3F0>
Going to <function view_profile at 0x02FCA4F0>
view_profile is a function in a completely different app.
, login_required(profile,'student')),
(r'editprofile/
This is for an app called student. If the user goes to /student/profile they should get the profile view. If they go to /student/editprofile they should get the editprofile view. I setup a function called login_required which does some checks on the user. It's a little more complicated than I could handle with just annotations.
Here's login_required:
Anyways, the weird thing is that, when I visit /student/profile, even though I get to the right page, login_required prints the following:
Why is it printing both? Why is it trying to visit both?
Even weirder, when I try to visit /student/editprofile, the profile page is what loads and this is what's printed:
view_profile is a function in a completely different app.
, login_required(editprofile,'student')),
)
This is for an app called student. If the user goes to /student/profile they should get the profile view. If they go to /student/editprofile they should get the editprofile view. I setup a function called login_required which does some checks on the user. It's a little more complicated than I could handle with just annotations.
Here's login_required:
Anyways, the weird thing is that, when I visit /student/profile, even though I get to the right page, login_required prints the following:
Why is it printing both? Why is it trying to visit both?
Even weirder, when I try to visit /student/editprofile, the profile page is what loads and this is what's printed:
view_profile is a function in a completely different app.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这两种模式:
都匹配
http://your-site/student/editprofile
。尝试:
Django 使用模式首先匹配的视图 (请参阅此处的第 3 点)。
, login_required(editprofile,'student')),Django 使用模式首先匹配的视图 (请参阅此处的第 3 点)。
, login_required(profile,'student')), (r'editprofile/都匹配
http://your-site/student/editprofile
。尝试:
Django 使用模式首先匹配的视图 (请参阅此处的第 3 点)。
, login_required(editprofile,'student')),都匹配
http://your-site/student/editprofile
。尝试:
Django 使用模式首先匹配的视图 (请参阅此处的第 3 点)。
These two patterns:
Both match
http://your-site/student/editprofile
.Try:
Django uses the view who's pattern matches first (see number 3 here).
, login_required(editprofile,'student')),Django uses the view who's pattern matches first (see number 3 here).
, login_required(profile,'student')), (r'editprofile/Both match
http://your-site/student/editprofile
.Try:
Django uses the view who's pattern matches first (see number 3 here).
, login_required(editprofile,'student')),Both match
http://your-site/student/editprofile
.Try:
Django uses the view who's pattern matches first (see number 3 here).
不知道为什么你不能使用标准的 @login_required 装饰器 - 似乎你的版本实际上提供了更少功能,因为它总是重定向到
\
,而不是实际的登录视图。无论如何,两者都被打印的原因是因为
print
语句位于装饰器的顶层,因此在 urlconf 被评估时执行。如果你把它放在内部new_view
函数中,它只会在实际调用时执行,并且应该只打印相关的视图名称。Not sure why you can't use the standard @login_required decorator - it seems that your version actually provides less functionality, given that it always redirects to
\
, rather than the actual login view.In any case, the reason why both are printed is because the
print
statement is in the top level of the decorator, and thus is executed when the urlconf is evaluated. If you put it in the innernew_view
function, it will only be executed when it is actually called, and should print only the relevant view name.您的
login_required
看起来像是一个 python 装饰器。你有什么理由需要将它放在你的 urls.py 中?我认为当读取 urlpatterns 以确定要执行哪个视图时,会评估 print 'Going to '+str(view) 行。看起来很奇怪,但我认为这不会伤害你。
print 'Going to '+str(view)
行不会在每次点击视图时执行,只有在评估 url 模式时才会执行(我认为)。new_view
中的代码是唯一会作为视图的一部分执行的代码。Your
login_required
looks like it's a python decorator. Any reason you need to have it in your urls.py?I think the
print 'Going to '+str(view)
line is getting evaluated whenurlpatterns
is read to determine which view to execute. It looks weird, but I don't think it'll hurt you.The line
print 'Going to '+str(view)
will not be executed every time the view is hit, only when the url pattern is evaluated (I think). The code innew_view
is the only code that will execute for certain as part of the view.