Reputation: 205
I have following piece of code
. Can anyone please help me understand what is actually going on in this code?
Especially, self.request.GET.get
and page < 1 and 1 or page
part.
def get(self, *v, **kv):
page = int( self.request.GET.get('page', 1) )
page = page < 1 and 1 or page
items_per_page = int( self.request.GET.get('items_per_page', 500))
items_per_page = items_per_page < 1 and 500 or items_per_page
from_date = convert_to_utc(parse_datetime(self.request.GET.get('from')))[0] \
or datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
to_date = convert_to_utc(parse_datetime(self.request.GET.get('to')))[0]
Upvotes: 0
Views: 2245
Reputation: 2381
@mhawke posted a great answer, but I still want to expand on it a bit.
Here is the webapp2 documentation for the request object. I highly recommend taking a look at that, and also the Webob documentation for the request, because webapp2 Requests and Responses are taken from the Webob framework (go ahead and take a look at the response docs while you're at it).
An important thing to note is that the GET data is a multi-dict, which also comes from the Webob framework. A multidict is basically a dict, but one key can have multiple values. Here is an example from the webapp2 docs:
request = Request.blank('/test?check=a&check=b&name=Bob')
# The whole MultiDict:
# GET([('check', 'a'), ('check', 'b'), ('name', 'Bob')])
get_values = request.GET
# The last value for a key: 'b'
check_value = request.GET['check']
# All values for a key: ['a', 'b']
check_values = request.GET.getall('check')
# An iterable with all items in the MultiDict:
# [('check', 'a'), ('check', 'b'), ('name', 'Bob')]
request.GET.items()
That info will come in handy if you end up using checkboxes to provide a list of values for one key (a "check all that apply" section on a form).
So in your code, self.request.GET.get('page', 1)
is retrieving the value for page
from the multidict, and returning 1 if that key is not found. This same logic is applied for the key items_per_page
, from
, and to
: retrieve the value for that key, and return the default value provided if the key is not found.
Then you have these two lines:
page = page < 1 and 1 or page
and
items_per_page = items_per_page < 1 and 500 or items_per_page
As @mhawke stated, this is a nasty way of saying:
if page < 1:
page = 1
if items_per_page < 1:
items_per_page = 500
In fact, if you get a chance you should change that code to be more readable.
Upvotes: 1
Reputation: 87134
self.request.GET
is provided by the webapp2 framework through the class in which get()
is implemented. It provides your code with access to a dictionary containing any query string parameters that were sent with the HTTP request, e.g. a URL such as:
http://localhost/resource?page=1&items_per_page=20
has two parameters in the query string: page
and items_per_page
with values 1 and 20 respectively. webapp2 processes the URL and provides your application with a dictionary containing these parameters, e.g. self.request.GET
might look like this:
{'page': 1, 'items_per_page': 20, ...}
self.request.GET.get()
performs a lookup in the dictionary for the requested key (e.g. page
) and returns its value if the key is present in the dictionary. If the key is not in the dictionary a default value is returned; for self.request.GET.get('page', 1)
the default value would be 1 if the URL did not contain the page
query parameter. See dict.get()
for details.
The next bit is a nasty way of defaulting to page 1 if the value supplied in the query string is less than 1:
page = page < 1 and 1 or page
can be written like this:
page = ((page < 1) and 1) or page
If the user supplied value of page is less than 1, page < 1
will be True
, then True and 1
will evaluate to 1 - and so 1 is used as the value of page. Any value >=1 will result in page < 1
being False
so the or
clause will be the value of the expression.
This can be rewritten in a much more readable way like this:
if page < 1:
page = 1
or like this:
page = 1 if page < 1 else page
which even more clearly shows the intention of the code.
Upvotes: 3