Cómo manejar request.GET con múltiples variables para el mismo parámetro en Django

82

En una vista de Django puede acceder a request.GET['variablename'], por lo que en su vista puede hacer algo como esto:

myvar = request.GET['myvar']

El request.GET['myvar']tipo de objeto real es:

<class 'django.http.QueryDict'>

Ahora, si desea pasar varias variables con el mismo nombre de parámetro, es decir:

http://example.com/blah/?myvar=123&myvar=567

Le gustaría que se listdevolviera una Python para el parámetro myvar, luego haga algo como esto:

for var in request.GET['myvar']:
    print(var)

Sin embargo, cuando intente que solo obtenga el último valor pasado en la URL, es decir, en el ejemplo anterior, obtendrá 567 , y el resultado en el shell será:

5
6
7

Sin embargo, cuando haces una impresión request.GET, parece que tiene un listie:

<QueryDict: {u'myvar': [u'123', u'567']}>

Ok Actualización: está diseñado para devolver el último valor, mi caso de uso es que necesito una lista.

de los documentos de django:

QueryDict. getitem (clave) Devuelve el valor de la clave dada. Si la clave tiene más de un valor, getitem () devuelve el último valor. Genera django.utils.datastructures.MultiValueDictKeyError si la clave no existe. (Esta es una subclase del KeyError estándar de Python, por lo que puede limitarse a detectar KeyError

QueryDict.getlist (clave) Devuelve los datos con la clave solicitada, como una lista de Python. Devuelve una lista vacía si la clave no existe. Está garantizado devolver una lista de algún tipo.

Actualización: si alguien sabe por qué los desarrolladores de django han hecho esto, hágamelo saber, parece contrario a la intuición mostrar una lista y no se comporta como tal. ¡No muy pitónico!

ismail
fuente
4
Creo que el razonamiento es que debe saber si esperar una lista o un valor individual. QueryDict.getitem no debería devolver una lista a veces, un elemento individual otras veces, entonces todos siempre tendrían que verificar su tipo de devolución para manejarlo correctamente.
jgiles

Respuestas:

180

Quieres la función getlist () del objeto GET:

request.GET.getlist('myvar')
AndrewF
fuente
10
Es posible que deba agregar un "[]" al final del nombre de var si está usando jquery para publicar elementos.
Danny Staple
2
Sabía sobre getlist pero el "[]" me tiró. Además, tengo un amigo llamado Andy Staple, y por un segundo pensé que sabía mucho más sobre Django de lo que yo pensaba. Eso también me desconcertó.
kungphu
1
Esto debe colocarse en todos los documentos de Django, los documentos de Django Rest Framework y al revés en mi frente. Esto realmente me tomó por sorpresa
Anthony Manning-Franklin
Parece que Django dejó caer la pelota en ese, no estoy seguro de si fue intencional
NaturalBornCamper
1

Otra solución es crear una copia del objeto de solicitud ... Normalmente, no puede iterar a través de un objeto request.GET o request.POST, pero puede hacer tales operaciones en la copia:

res_set = request.GET.copy()
for item in res_set['myvar']:
    item
...
Ángel caido
fuente
2
¿Estás seguro? esto no cambia el comportamiento del QueryDict en absoluto para mí. acabo de conseguir otro QueryDict con el mismo "limitación"
tuercas