Introduction to some advanced concepts of URL view functions in Django, djangourl view Functions

Source: Internet
Author: User

Introduction to some advanced concepts of URL view functions in Django, djangourl view Functions

Speaking of the branch of the Request Method, let's take a look at what good methods can be used to implement it. Consider the URLconf/view Design:

# urls.pyfrom django.conf.urls.defaults import *from mysite import viewsurlpatterns = patterns('',  # ...  (r'^somepage/$', views.some_page),  # ...)# views.pyfrom django.http import Http404, HttpResponseRedirectfrom django.shortcuts import render_to_responsedef some_page(request):  if request.method == 'POST':    do_something_for_post()    return HttpResponseRedirect('/someurl/')  elif request.method == 'GET':    do_something_for_get()    return render_to_response('page.html')  else:    raise Http404()

In this example, the ''some_page () ''view function processes two request methods: ''post'' and ''get. The only thing they have in common is sharing a URL address: ''/somepage /. ''as you can see, processing ''post'' and ''get'' in the same view function is a very basic and rough method. A better design habit should be to use two separate view functions-one for processing the ''post'' request and the other for processing the ''get'' request, then, call them separately in the corresponding place.

We can do this: first write a view function and then assign other views to execute some of our custom program logic before or after. The following example shows how this technology helps us improve the simple ''some_page () ''' view on the front:

# views.pyfrom django.http import Http404, HttpResponseRedirectfrom django.shortcuts import render_to_responsedef method_splitter(request, GET=None, POST=None):  if request.method == 'GET' and GET is not None:    return GET(request)  elif request.method == 'POST' and POST is not None:    return POST(request)  raise Http404def some_page_get(request):  assert request.method == 'GET'  do_something_for_get()  return render_to_response('page.html')def some_page_post(request):  assert request.method == 'POST'  do_something_for_post()  return HttpResponseRedirect('/someurl/')# urls.pyfrom django.conf.urls.defaults import *from mysite import viewsurlpatterns = patterns('',  # ...  (r'^somepage/$', views.method_splitter, {'GET': views.some_page_get, 'POST': views.some_page_post}),  # ...)

Let's take a look at how the code works from the beginning:

We have written a new view, ''method_splitter () '', which calls the corresponding view based on the value returned by ''request. method. We can see that it has two key parameters: ''get'' and ''post''. It may be a * view function *. If ''request. method'' returns ''get'', it automatically calls the ''get'' view. If ''request. method'' returns ''post'', it calls the ''post'' view. If ''request. method ''returns other values (such as ''head''), or does not submit ''get'' or ''post'' to this function, then it will throw a ''http404'' error.

In URLconf, we refer ''/somepage/'' To The ''method_splitter () ''function, and pass the ''get'' and ''post'' parameters required by the view function to it.

Finally, we break down the ''some_page () ''view into two view functions: ''some_page_get ()'' and ''some_page_post ()''. This is much more elegant than squeezing all logic into a single view.

Note: Technically, these view functions do not need to check ''request. method'', because ''method_splitter () ''has already been done for them. (For example, when ''some_page_post () ''is called, we can be sure that the value returned by ''request. method'' is ''post ''.) Of course, this is not only safer but also better documented code. Here we make a assumption that ''request. method'' can work as we expected.

Now we have a good view function that can be used for general purposes. The returned values of ''request. method'' are encapsulated in the function to distribute different views. There is nothing about ''method_splitter () ''. Of course, we can reuse them in other projects.

However, when we do this, we can still improve ''method_splitter ''. We can see from the code that it assumes that the ''get'' and ''post'' views do not need any other parameters except the ''request. So what if we want to use ''method_splitter ''to capture characters from the URL or receive views with some optional parameters?

To achieve this, we can use a variable parameter with asterisks in an elegant feature in Python. We will first show these examples and then explain them.

def method_splitter(request, *args, **kwargs):  get_view = kwargs.pop('GET', None)  post_view = kwargs.pop('POST', None)  if request.method == 'GET' and get_view is not None:    return get_view(request, *args, **kwargs)  elif request.method == 'POST' and post_view is not None:    return post_view(request, *args, **kwargs)  raise Http404

Here, we reconstruct method_splitter () and remove the GET and POST keyword parameters. Instead, we support the use of * args and ** kwargs (note *). This is a Python feature, allows a function to accept dynamic, variable, and parameter names that are only known at runtime. If you add a * sign before a function definition, all parameters passed to the function will be saved as a tuple. if you add two * numbers before a function definition, all the keyword parameters passed to the function will be saved as a dictionary.

For example

def foo(*args, **kwargs):  print "Positional arguments are:"  print args  print "Keyword arguments are:"  print kwargs

Let's see how it works.

>>> foo(1, 2, 3)Positional arguments are:(1, 2, 3)Keyword arguments are:{}>>> foo(1, 2, name='Adrian', framework='Django')Positional arguments are:(1, 2)Keyword arguments are:{'framework': 'Django', 'name': 'Adrian'}

Looking back, you can find that we use method_splitter () and * args to accept ** kwargs function parameters and pass them to the correct view. Any, but before doing so, we need to call the kwargs. pop () GETPOST parameter twice, if they are valid. (We can avoid KeyError caused by one or more missing keywords by specifying the default value of pop as None)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.