Dynamic URL configuration in Django

Source: Internet
Author: User
Tags timedelta

For example, an online bookstore will provide a URL for each book, such as:/books/243/,/books/81196/.

Let's create a third view to show the current time and the time of the time offset, which is the design: /time/plus/1/ Show Current time + 1 hours page /time/plus/2/ Show Current time + 2 hour page /time/plus/3/ Displays the current time + 3 hours of the page, and so on. The novice may consider writing different view functions to handle the amount of each time skew, and the URL configuration looks like this:
Urlpatterns = Patterns ("',    ('^time/$', Current_datetime), ('^time/plus/1/$', One_hour_ahead), ('^time/plus/2/$', Two_hours_ahead), ('^time/plus/3/$', Three_hours_ahead), ('^time/plus/4/$', Four_hours_ahead),)

It is clear that such treatment is not appropriate. Not only are there many redundant view functions, but the entire application is also limited to supporting predefined time periods, 2 hours, 3 hours, or 4 hours. If we were to implement 5 hours one day, we would have to create new view functions and configuration URLs separately, both repetitive and confusing. We need to do a little abstraction here and extract some of the common things out.

A little bit of advice on pretty URLs

If you have other web platform development experience (such as PHP or Java), you might think: Hey! Let's use the query string parameter! Just like the hours inside the/time/plus?hours=3 should be specified in the query string by the parameter hours (the parameter after the question mark).

You can do the same in Django (if you really want to do this, we'll show you how to do it later), but one of the core concepts of Django is that URLs must look beautiful. URL/TIME/PLUS/3/is clearer, simpler, and more readable, and can be easily read aloud because it is plain text and not as complex as a query string. Beautiful URLs are like a sign of a high-quality web app.

Django's URL configuration system allows you to easily set a nice URL, and try not to think about its opposite.

So, how do we design programs to handle any number of slack? The answer is: use a wildcard character (wildcard urlpatterns). As we mentioned before, a URL pattern is a regular expression. As a result, you can use d+ to match more than 1 numbers.

Urlpatterns = Patterns ("',    #  ...    (R'^time/plus/\d+/$', Hours_ahead),     #  ...)

Here to use # ... To indicate that other possible URL pattern definitions are omitted. (see above)

This URL pattern will match any URL similar to/time/plus/2/,/time/plus/25/, or even/time/plus/100000000000/. Further, let's limit it to the maximum allowable 99 hours, so that we allow only one or two numbers, and the syntax of the regular expression is \d{1,2}:

(R'^time/plus/\d{1,2}/$', Hours_ahead),

When building Web applications, it is important to consider as many possible data inputs as possible, and then decide which ones we can accept. Here we set a 99-hour period limit.

Another focus, the beginning of the regular expression string, is the letter "R". It tells Python that this is an original string and does not need to handle the backslash (escape character) inside. In a normal Python string, backslashes are used to escape special characters. For example, N escapes into a newline character. When you use R to mark it as an original string, Python no longer sees the backslash as an escape character. In other words, "n" is a two string: "" and "N". Because backslashes have conflicts in Python code and regular expressions, it is recommended that you use the original string when you define a regular expression in Python. From now on, all URL patterns in this article are in the original string. 10

Now that we have designed a URL with wildcards, we need a way to pass it to the view function so that we can handle all the time periods with just one view function. We use parentheses to identify the parameters in the URL pattern. In this example, we want to use these numbers as arguments, enclosing \d{1,2} in parentheses:

(R'^time/plus/(\d{1,2})/$', Hours_ahead),

If you are familiar with regular expressions, you should already understand that regular expressions also use parentheses to extract data from text. 2

The final urlconf contains the above two views, such as:

 from  django.conf.urls.defaults import  *from  mysite.views import   Hello, current_datetime, hours_aheadurlpatterns  = Patterns (  "   " ^ hello/$   " , hello), (R  "  ^time/$   "   " ^time/plus/(\d{1,2})/$  "  , Hours_ Ahead),)  

Now start writing the hours_ahead view.

Hours_ahead like the current_datetime we wrote before , the key difference is that it has an extra parameter, a time difference. Here is the View code:

 fromDjango.httpImportHttp404, HttpResponseImportdatetimedefhours_ahead (Request, offset):Try: Offset=int (offset)exceptValueError:RaiseHttp404 () DT= Datetime.datetime.now () + Datetime.timedelta (hours=offset) HTML=" 'll be%s.</body>"%(offset, DT)returnHttpResponse (HTML)

Let's analyze the code on a row-by-line basis:

The view function, Hours_ahead, has two parameters: request and offset. (see above)

Request is a HttpRequest object, just like in Current_datetime. Once again, it's okay: Each view always takes a HttpRequest object as its first argument. (see above)

Offset is extracted from the matching URL. For example: If the request URL is/time/plus/3/, then offset will be 3, if the request URL is/time/plus/21/, then offset will be 21. Note that the captured value is always a string (string) type, not an integer type, even if the string is entirely composed of numbers (for example: "21").

(Technically, the capture value is always Unicode objects, not a simple Python byte string, but there is no need to worry about these differences at this time.) )

Here we name the variable offset, you can also arbitrarily name it, as long as it conforms to the Python syntax. The variable name is irrelevant, and it is important that it is in its place, which is the second parameter of the function (after the request). You can also use keywords to define it, rather than using a location.

The first thing we want to do in this function is to raise the int () on offset. This converts the string value to an integer.

Note that if you call Int () on a value that cannot be converted to an integer type, Python throws an ValueError exception. such as: Int (' foo '). In this example, if we encounter a ValueError exception, we will turn to throw the django.http.Http404 exception--as you might expect: The final display of page 404 (Hint: the page does not exist).

Smart readers may ask: we use regular Expressions (d{1,2}) in the URL pattern to constrain it, just accept the numbers? In any case, offset is composed of numbers. The answer is: we will not do this because Urlpattern provides a "moderate but useful" level of input validation. In case this view function is called by other means, we still need to check the valueerror ourselves. The practice proves that it is better to not speculate the parameter value when implementing the View function. Loosely coupled, remember?

Next line, calculate the current date/time, and then add the appropriate number of hours. In the Current_datetime view, we have seen Datetime.datetime.now (). The new concept here is to perform arithmetic operations on date/time. We need to create a Datetime.timedelta object and add an Datetime.datetime object. The result is stored in the variable dt.

This line also explains why we are raising the int ()--datetime.timedelta function on offset to require the hours argument to be an integer type.

A small difference between this line and the previous line is that it uses a Python formatted string function with two values, not just a value. Therefore, there are two%s symbols in the string and a tuple of values to be inserted: (offset, DT).

Finally, an HTML HttpResponse is returned. Today, this approach is obsolete. 28

After writing the view function and URL configuration, start the Django Development server and use the browser to access http://127.0.0.1:8000/time/plus/3/to verify that it is working properly. And then the http://127.0.0.1:8000/time/plus/5/. And then the http://127.0.0.1:8000/time/plus/24/. Finally, visit http://127.0.0.1:8000/time/plus/100/to verify that the mode set in the URL configuration accepts only one or two digits; Django displays a page not found error, and 404 errors that were previously seen The same. Accessing the URL http://127.0.0.1:8000/time/plus/(no time difference defined) also throws a 404 error.

Dynamic URL configuration in Django

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.