2017-08-08 1 views
0

Ich habe folgendes Stück code. Kann mir bitte jemand helfen, zu verstehen, was eigentlich in diesem Code vor sich geht?Verstehen Anforderungsparameter in Python

Insbesondere self.request.GET.get und page < 1 and 1 or page Teil.

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] 
+0

Was ist 'self.request'? – Fejs

+0

Ich bin auch auf der Suche nach der Antwort derselben Frage. @Fejs – HamidArrivy

Antwort

3

self.request.GET wird durch den webapp2 Rahmen durch die Klasse zur Verfügung gestellt, in der get() implementiert ist. Es bietet Ihrem Code Zugriff auf ein Wörterbuch, das beliebige Abfragezeichenfolgenparameter enthält, die mit der HTTP-Anforderung gesendet wurden, z. eine URL wie:

http://localhost/resource?page=1&items_per_page=20

hat zwei Parameter in der Abfragezeichenfolge: items_per_pagepage und mit den Werten 1 bzw. 20. webapp2 verarbeitet die URL und versorgt Ihre Anwendung mit einem Wörterbuch, das diese Parameter enthält, z. self.request.GET könnte wie folgt aussehen:

{'page': 1, 'items_per_page': 20, ...} 

self.request.GET.get() führt eine Suche in dem Wörterbuch für die gewünschte Taste (z page) und gibt seinen Wert zurück, wenn der Schlüssel im Wörterbuch vorhanden ist. Wenn der Schlüssel nicht im Wörterbuch ist, wird ein Standardwert zurückgegeben. Für self.request.GET.get('page', 1) wäre der Standardwert 1, wenn die URL den Abfrageparameter page nicht enthält. Details siehe dict.get().


Das nächste Bit ist eine böse Art und Weise zu Seite von säumigen 1, wenn der Wert in der Abfragezeichenfolge geliefert wird, weniger als 1:

page = page < 1 and 1 or page 

kann wie folgt geschrieben werden:

page = ((page < 1) and 1) or page 

Wenn der vom Benutzer angegebene Seitenwert kleiner als 1 ist, wird page < 1True sein, dann wird True and 1 zu 1 ausgewertet - und so wird 1 als Seitenwert verwendet. Jeder Wert> = 1 führt dazu, dass page < 1False ist, so dass die or-Klausel der Wert des Ausdrucks ist.

Dies kann, wie dies in einem viel lesbarer Weise neu geschrieben werden:

if page < 1: 
    page = 1 

oder so:

page = 1 if page < 1 else page 

, die noch deutlicher die Absicht des Codes zeigt.

+0

Ich habe keine Worte, um Ihnen zu danken. Das ist alles was ich sagen kann. Akzeptierte deine Antwort direkt. Sehr schöne Erklärung. @mhawke kannst du mir bitte die Zeilen in meinen nächsten Kommentaren erklären? – HamidArrivy

+0

query = Task.query (Task.start_datetime> = from_date, Vorfahr = user_key) – HamidArrivy

+0

query = query.filter (Task.entity_ids.IN (entity_ids)) – HamidArrivy

0

@mhawke hat eine großartige Antwort geschrieben, aber ich möchte noch ein wenig weitermachen.

Here is the webapp2 documentation für das Anfrageobjekt. Ich empfehle dringend, einen Blick darauf zu werfen, und auch die Webob documentation für die Anfrage, weil Webapp2 Anfragen und Antworten aus dem Webob-Framework entnommen werden (gehen Sie voran und werfen Sie einen Blick auf die Antwortdokumente, während Sie gerade dabei sind).

Eine wichtige Sache zu beachten ist, dass die GET-Daten eine multi-dict ist, die auch aus dem Webob-Framework stammt. Ein Multidict ist grundsätzlich ein Diktat, aber ein Schlüssel kann mehrere Werte haben.Hier ist ein Beispiel aus der 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() 

Das Info nützlich sein, wenn Sie Kontrollkästchen am Ende mit einer Liste von Werten für einen Schlüssel, um (a „alle überprüfen, die gelten,“ auf einem Formular) .

In Ihrem Code ruft self.request.GET.get('page', 1) den Wert für page aus dem multidict ab und gibt 1 zurück, wenn dieser Schlüssel nicht gefunden wird. Dieselbe Logik wird für den Schlüssel items_per_page, from und to angewendet: Ruft den Wert für diesen Schlüssel ab und gibt den Standardwert zurück, wenn der Schlüssel nicht gefunden wird.

Dann haben Sie diese beiden Zeilen:

page = page < 1 and 1 or page 

und

items_per_page = items_per_page < 1 and 500 or items_per_page 

Wie @mhawke erwähnt, ist dies eine unangenehme Art zu sagen:

if page < 1: 
    page = 1 
if items_per_page < 1: 
    items_per_page = 500 

In der Tat, wenn Sie erhalten eine Chance, dass Sie diesen Code ändern sollten, um besser lesbar zu sein.