View method requests
So far you've worked with Django
view methods and their input -- a request
object and
parameters -- as well as their output, consisting of generating a
direct response or relying on a template to generate a response.
However, now it's time to take a deeper look at what's available in
view method requests and the various alternatives to generate view
method responses.
The request
reference you've placed unquestionably in view methods up to this
point, is an instance of the
django.http.request.HttpRequest
class[3]. This request
object
contains information set by entities present before a view method:
a user's web browser, the web server that runs the application or a
Django middleware class configured on the application.
The following list shows some of
the most common attributes and methods available in a
request
reference:
request.method
.- Contains the HTTP method used for the request (e.g.GET
,POST
).request.GET
orrequest.POST
.- Contains parameters added as part of a GET or POST request, respectively. Parameters are enclosed as adjango.http.request.QueryDict
[4] instance.request.POST.get('name',default=None)
.- Gets the value of thename
parameter in a POST request or getsNone
if the parameter is not present. Notedefault
can be overridden with a custom value.request.GET.getlist('drink',default=None)
.- Gets a list of values for thedrink
parameter in a GET request or gets an empty listNone
if the parameter is not present. Notedefault
can be overridden with a custom value.request.META
.- Contains HTTP headers added by browsers or a web server as part of the request. Parameters are enclosed in a standard Python dictionary where keys are the HTTP header names -- in uppercase and underscore (e.g.Content-Length
as keyCONTENT_LENGTH
).request.META['REMOTE_ADDR']
.- Gets a user's remote IP address.request.user
.- Contains information about a Django user (e.g. username, email) linked to the request. Noteuser
refers to the user in thedjango.contrib.auth
package and is set via Django middleware, described later in this chapter.
As you can attest from this brief
list, the request
reference contains a lot of
actionable information to fulfill business logic (e.g. you can
respond with certain content based on geolocation information from
a user's IP address). There are well over fifty
request
options available between
django.http.request.HttpRequest
&
django.http.request.QueryDict
attributes and methods,
all of which are explained in parts of the book where they're
pertinent -- however you can review the full extent of
request
options in the footnote link of the django.http.request.HttpRequest
class.
Once you're done extracting
information from a request
reference and doing related
business logic with it (e.g. querying a database, fetching data
from a third party REST service) you then need to set up data in a
view method to send it out as part of a response.
To set up data in a Django view method you first need to declare it or extract it inside the method body. You can declare strings, numbers, lists, tuples, dictionaries or any other Python data structure.
Once you declare or extract the data inside a view method, you create a dictionary to make the data accessible on Django templates. The dictionary keys represent the reference names for the template, while the values are the data structures themselves. Listing 2-23 illustrates a view method that declares multiple data structures and passes them to a Django template.
Listing 2-23 Set up dictionary in Django view method for access in template
from django.shortcuts import render def detail(request,store_id=1,location=None): # Create fixed data structures to pass to template # data could equally come from database queries # web services or social APIs STORE_NAME = 'Downtown' store_address = {'street':'Main #385','city':'San Diego','state':'CA'} store_amenities = ['WiFi','A/C'] store_menu = ((0,''),(1,'Drinks'),(2,'Food')) values_for_template = {'store_name':STORE_NAME, 'store_address':store_address, 'store_amenities':store_amenities, 'store_menu':store_menu} return render(request,'stores/detail.html', values_for_template)
Notice in listing 2-23 how the
render
method includes the
values_for_template
dictionary. In previous examples,
the render
method just included the
request
object and a template to handle the request.
In listing 2-23, a dictionary is passed as the last
render
argument. By specifying a dictionary as the
last argument, the dictionary becomes available to the template --
which in this case is stores/detail.html
.
Tip If you plan to access the same data on multiple templates, instead of declaring it on multiple views, you can use a context processor to declare it once and make it accessible on all project templates. The next chapter on Django templates discusses this topic of context processors.
The dictionary in listing 2-23 contains keys and values that are data structures declared in the method body. The dictionary keys become references to access the values inside Django templates.
Although the next chapter covers Django templates in-depth, the following snippet shows how to output the dictionary values in listing 2-23 using the {{}} syntax.<h4>{{store_name}} store</h4> <p>{{store_address.street}}</p> <p>{{store_address.city}},{{store_address.state}}</p> <hr/> <p>We offer: {{store_amenities.0}} and {{store_amenities.1}}</p> <p>Menu includes : {{store_menu.1.1}} and {{store_menu.2.1}}</p>The first declaration
{{store_name}}
uses the standalone key to display theDowntown
value. The other access declarations use dot(.
) notation because the values themselves are composite data structures.Thestore_address
key contains a dictionary, so to access the internal dictionary values you use the internal dictionary key separated by a dot(.
).store_address.street
displays the street value,store_address.city
displays the city value andstore_address.state
displays the state value.Thestore_amenities
key contains a list which uses a similar dot(.) notation to access internal values. However, since Python lists don't have keys you use the list index number.store_amenities.0
displays the first item in liststore_amenities
andstore_amenities.1
displays the second item in list store_amenities.
The
store_menu key
contains a tuple of tuples which also requires a number on account of the lack of keys.{{store_menu.1.1}}
displays the second tuple value of the second tuple value ofstore_menu
and{{store_menu.2.1}}
displays the second tuple value of the third tuple ofstore_menu
.