You want to access url parameters, extra options and define optional url parameters inside a Django view method
Use regular expressions and Django's special syntax to handle url parameters or the url options dictionary to define url extra options. Use default values in Django view methods to define optional url parameters. Use the HTTP
request object in view methods to gain access to parameters.
In a previous recipe you learned how Django uses regular expressions to match url patterns and send requests to a Django view method. This exercise though was limited to discarding the url information after the initial pattern match. If you didn't do this last exercise see the recipe 'Set up content, understand Django urls, templates and apps'.
Sometimes it's helpful or even necessary to pass url information to the Django view method. For example, if you have several urls like
/stores/3, the last part of the url illustrates a pattern. In this case
3 refer to store ids. It can be helpful or necessary to relay this url information to the Django view method so it can get more information about the store id (e.g. query a database), information that can then be passed to a Django template for presentation. This process requires that part of the url be treated as a parameter.
To handle url parameters Django uses a special syntax in combination with regular expressions. Listing 1 shows a url example that creates a parameter named
(?P<store_id>\d+) syntax in listing 1. The
?P tells Django to convert the matching value to a parameter and
<store_id> assigns the matching value to a variable called
store_id. The final piece of the url parameter syntax
\d+ is a regular expression to determine the matching value, in this case the matching value are digits (i.e.numbers).
The important functionality of the syntax in listing 1 is the matching url value is treated as a parameter. For example, for the url
/stores/1 the value
1 is assigned to the
store_id parameter, for the url
/stores/2 the value
2 is passed to the
store_id parameter. For a url like
/stores/downtown the regular expression pattern doesn't match -- because
downtown are letters not digits -- so no action is taken.
If a url match occurs for listing 1, the request is sent directly to the Django view method
coffeehouse.stores is the package name,
views.py the file inside the
stores app and
detail the name of the view method. Listing 2 illustrates the Django view method to access the
Notice in listing 2 how the
detail method has two arguments. The first argument is a
request object, this is always the same for all Django view methods that handle url requests. The second argument is the parameter passed by the url. It's important to note the names of url parameters must match the names of the method arguments. In this case notice in listing 1 the parameter name is
store_id and in listing 2 the method argument is also named
With access to the url parameter via the view method argument, the method can execute logic with the parameter (e.g. query a database) that can then be passed to a Django template for presentation. In the next recipe I'll describe how to pass data from a view method to a Django template.
Url parameters can also be made optional to leverage the same view method multiple times. Parameters can be made optional by assigning a default value to a view method argument. Observe listing 3 which includes a new url that calls the same view method (
coffeehouse.stores.views.detail) but doesn't define a parameter.
If you called the url
stores without modifying the
detail method in listing 2 you would get an error. The error occurs because the
detail view method expects a
store_id argument which isn't provided by the url. To fix this problem, you can define a default value for the
store_id as illustrated in listing 4.
Notice in listing 4 how the
store_id argument has an assignment
=1. This means the argument will have a default value of
1 in case the view method is called without
store_id. This approach allows you to leverage the same view method to handle multiple urls with optional parameters.
In addition to accessing url parameters inside view methods, it's also possible to access extra options from the url definition. These extra options are defined inside a general purpose dictionary declared as a third argument in a url definition. After the view method declaration, you add a dictionary with the key-value pairs you wish to access inside the view method.
For example, you can change the url in listing 3 from
location key becomes a url extra option that's passed as a parameter to the view method.
Url extra options are assigned like url parameters. So to access a url extra option inside a view method you'll need to modify the method signature to accept an argument with the same name as the url extra option. In this case, the method signature
def detail(request,store_id=1): would need to change to
def detail(request,store_id=1,location=None): -- notice the
location argument is made optional by assigning a default value of
Finally, it's also possible to access url parameters separated by
& inside Django view methods. On certain urls -- those made by HTTP GET requests -- parameters are added to a url with
? followed by
parameter_name=parameter_value separated by
&. These type of parameters can be accessed easily inside a view method using the
request object, instead of attempting to use a url regular expression.
Take for example the url
1 value can easily be assigned to a parameter by a url regular expression, but the remaining parameters can be very difficult to assign with a regular expression. Since Django urls just match patterns, the arguments separated by
& aren't altered and are accessible in a view method's
request object. Listing 5 illustrates how to extract arguments separated by
Listing 5 uses the syntax
request.GET.get(<parameter>, ''). If the parameter is present in
request.GET it extracts the value and assigns it to a variable for further usage, if the parameter is not present then the parameter variable is assigned an empty value of
''. This last process is designed to extract parameters from an HTTP GET request, however Django also support the syntax
request.POST.get to extract parameters from an HTTP POST request.