This article describes how to wrap view functions in the Python Django framework, that is, the requires_login method, if you need it, you can refer to our final View technique and use an advanced python technology. Suppose you find that you have repeated a large number of code in different views, just like this example:
def my_view1(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') # ... return render_to_response('template1.html')def my_view2(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') # ... return render_to_response('template2.html')def my_view3(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') # ... return render_to_response('template3.html')
Here, each view starts to check the request. if the user has been authenticated, yes, the current user has successfully logged on to the site or else it will redirect/accounts/login/(note that although we have not talked about the request. user, but Chapter 14 will talk about it. as you can imagine, request. user: indicates whether the current user is logged on or anonymous)
If we can remove the duplicate generations from each view and specify them only when authentication is required, it will be perfect. We can achieve this by using a view packaging. Take a moment to look at this:
def requires_login(view): def new_view(request, *args, **kwargs): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') return view(request, *args, **kwargs) return new_view
Function requires_login, input a view function view, and return a new view function new_view. the new view function new_view defines the processing request in the function requires_login. user. is_authenticated () to determine whether to execute the original view function
Now, we can remove if not request. user. is_authenticated () from views for verification. we can easily use requires_login in URLconf for packaging.
from django.conf.urls.defaults import *from mysite.views import requires_login, my_view1, my_view2, my_view3urlpatterns = patterns('', (r'^view1/$', requires_login(my_view1)), (r'^view2/$', requires_login(my_view2)), (r'^view3/$', requires_login(my_view3)),)
The optimized code is the same as the previous function, but the code redundancy is reduced. now we have built a beautiful and general function requires_login () to help us modify all views that require verification.
Including other URLconf
If you try to use your code on multiple Django-based sites, you should consider processing your URLconf in an included manner.
At any time, your URLconf can contain other URLconf modules. This is necessary for websites whose root directory is based on a series of URLs. For example, URLconf contains other URLConf:
from django.conf.urls.defaults import *urlpatterns = patterns('', (r'^weblog/', include('mysite.blog.urls')), (r'^photos/', include('mysite.photos.urls')), (r'^about/$', 'mysite.views.about'),)
The admin module has its own URLconf. you only need to add include to your own code.
Here is a very important thing: the regular expression pointing to include () in this example does not contain a $ (string end match), but contains a diagonal bar. Whenever Django encounters include (), it truncates the matched URL and sends the remaining string to the contained URLconf for further processing.
Let's continue with this example. here is the contained URLconf mysite. blog. urls:
from django.conf.urls.defaults import *urlpatterns = patterns('', (r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail'), (r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail'),)
Through these two URLconf, the following are some examples of request processing:
- /Weblog/2007/: in the first URLconf, the mode R' ^ weblog/'is matched. Because it is an include (), Django will cut off all matched texts. here it is 'weblog /'. The remaining part of the URL is 2007/, which will be matched in the first line of mysite. blog. urls URLconf. The remaining part of the URL is 2007/, which matches the mysite. blog. urlsURL setting in the first line.
- /Weblog // 2007/(including two slashes) in the first URLconf, R' ^ weblog/'matches because it has an include (), and django removes the matched part, in this example, the matching part is 'weblog/'. The remaining part is/2007/(there is a slash at the beginning) and does not match mysite. blog. any row in urls.
- /About/: match the mysite. views. about view in the first URLconf file.