So far, we have created only simple URL patterns in the URLconf file. Django's URL dispatcher can handle much more complicated URLs by adding more complicated URL patterns to the URLconf file. These patterns will help you define the behavior of your website with regard to the URLs that are being accessed.
This section discusses how to add expressions to URL patters that will allow you to control what type of data will be allowed in URLs. It also covers assigning names to expressions that correlate to arguments that can be passed into your views when they are called by the URL dispatcher.
In the previous section, you defined an URL pattern for the URL /People/Info. This is the most basic type of URL pattern—a simple name. Django also allows you to include expressions in the URL patterns, giving you much more flexibility.
By the Way
Each expression you define in the view is passed to the view function as an argument, so you need to modify the definition of the view function in the views.py file to handle the additional arguments.
The following are some of the more common expressions that can be used to define URL patterns:
. (dot) matches any character. The following pattern matches the URL /People/Info1/:
(r'^People/Info./$', 'iFriends.People.views.details'),
\d matches any digit. The following pattern matches the URL /People/Info/1/:
(r'^People/Info/\d/$', 'iFriends.People.views.details'),
[A-Z] matches any character from A to Z, uppercase. The following pattern matches the URL /People/Info/A/ but not /People/Info/a/:
(r'^People/Info/[A-Z]/$', 'iFriends.People.views.details'),
[a-z] matches any character from a to z, lowercase. The following pattern matches the URL /People/Info/a/ but not /People/Info/A/:
(r'^People/Info/[a-z]/$', 'iFriends.People.views.details'),
[A-Za-z] matches any character from a to z, uppercase or lowercase. The following pattern matches the URLs /People/Info/a/ and /People/Info/A/:
(r'^People/Info/[A-Za-z]/$', 'iFriends.People.views.details'),
[^/]+ matches all characters until a slash is encountered. The following pattern matches the URL /People/Info/123abc***/:
(r'^People/Info/[^/]+/$', 'iFriends.People.views.details'),
+ matches one or more of the previous characters. The following pattern matches the URLs /People/Info/Person1, /People/Info/Person12/, and /People/Info/Person123/:
(r'^People/Info/Person\d+/$', 'iFriends.People.views.details'),
? matches zero or more of the previous characters. The following pattern matches the URLs /People/Info/, /People/Info1/, and /People/Info12/:
(r'^People/Info/\d?/$', 'iFriends.People.views.details'),
{n1,n2} matches a number of the previous characters between n1 and n2, inclusive. The following pattern matches the URLs /People/Info/1/ through /People/Info/99/:
(r'^People/Info/\d{1,2}/$', 'iFriends.People.views.details'),
After you have added an expression to a pattern in the URLconf file, you can pass it to the view function as an argument. This allows you to use passed arguments to define the behavior of the view instead of having to access data from GET and POST data. The result is that your URLs have a much more elegant design than if you used PHP or CGI scripts.
By the Way
The values of expressions that Django passes as arguments to the view function are string format even if the pattern specifies digits using \d. If you need to use those values as a number, you must convert them first.
You need to assign an argument to the view function definition for each expression that you add to the URL pattern for the view.
To show this, we will look at an example of an URL pattern for a search application that provides a view function doc_search() that queries a database of documents by document number. In the example, we want to define an URL pattern for a view that searches only one document at a time. The following URL pattern is designed to collect the document number and pass it to the doc_search() function:
(r'^docSearch/\d{1,3}/$', 'iHistory.docSearch.views.doc_search'),
The URL to access this pattern is as follows, where # can be any document number between 1 and 9999:
". . ./docSearch/#"
The corresponding view definition in the views.py file would look something like this:
def doc_search(request, doc_number):
We can add a second expression to another pattern to also provide a specific page number argument by modifying the URL pattern, as shown here:
(r'^pageSearch/\d{1,3}/\d{1,4}/$', 'iHistory.docSearch.views.page_search'),
The URL to access this pattern is as follows, where #a can be any document number between 1 and 9999, and #b can be any page number between 1 and 999:
". . ./docSearch/#a/#b"
The corresponding view definition in the views.py file would look something like this:
def page_search(request, doc_number, page_number):
In the examples in the preceding section, the arguments that were captured were passed to the view function as positional arguments. As the URLconf file grows and more patterns are defined, this can become confusing.
Assigning an argument name to each expression allows you to keep your URLconf file much less confusing. The arguments are then passed to the view function as keyword arguments that do not require a specific order.
The syntax to assign an argument name to an expression is as follows, where name is the name of the argument in the view function, and pattern is the matching pattern:
(?P<name>pattern)
The following example modifies the examples from the previous section to use named expressions:
(r'^pageSearch/(?P<page_number>\d{1,4})/(?P<doc_number>\d{1,3}/$', 'iHistory.docSearch.views.page_search'), (r'^pageSearch/(?P<doc_number>\d{1,3}/(?P<page_number>\d{1,4})/$', 'iHistory.docSearch.views.page_search'),
Both of these examples work exactly the same way, because the doc_number and page_number arguments are passed to the page_search() function as a keyword dictionary.
Did you Know?
Django allows you to have multiple patterns point to the same view, as long as you can define initial values to the view's arguments. For example, consider the following view function:
def view_page(request, pgnum="1"):
Both of the following URL patterns could be added to the URLconf file:
(r'^viewPage/$', 'iBooks.views.view_page'), (r'^viewPage/\d{1,4}/$', 'iBooks.views.view_page'),
Try It Yourself: Add a Named Expression to an URL PatternIn the preceding "Try It Yourself" section, you added a details() view to the URLconf file. The details() view appears in the web browser when you access the http://127.0.0.1:8000/Info URL. In this section, you modify the URLconf file to also allow an argument named pID (person ID) to be specified in the URL. You will modify the URLconf file to have two different URL patterns that both point to the details() view. The first will not pass a parameter to the view, and the second one will. Follow these steps to add an URL pattern with a named expression URLconf file and update the details() view:
Watch Out! The Django URL dispatcher is case-sensitive. Make certain that the case matches between the patterns in the URLconf file and the views.py file. Listing 4.3 shows the complete urls.py file. Listing 4.3. Full Contents of the iFriends\urls.py File with an Entry that Passes the pID to the details() View Function
Listing 4.4 shows the complete urls .py file. Listing 4.4. Full Contents of the iFriends\People\views.py File with Additional pID Argument Code
|