Django'da aynı parametre için birden çok değişkenle request.GET nasıl işlenir


82

Bir Django görünümünde öğesine erişebilirsiniz request.GET['variablename'], böylece görünümünüzde aşağıdaki gibi bir şey yapabilirsiniz:

myvar = request.GET['myvar']

Gerçek request.GET['myvar']nesne türü:

<class 'django.http.QueryDict'>

Şimdi, aynı parametre adına sahip birden çok değişken geçirmek istiyorsanız, yani:

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

listParametre için bir python'un döndürülmesini istersiniz myvar, sonra şöyle bir şey yapın:

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

Ancak, yalnızca url'de geçen değeri almayı denediğinizde, yani yukarıdaki örnekte 567 elde edersiniz ve kabuktaki sonuç şöyle olur:

5
6
7

Bununla birlikte, bir baskı yaptığınızda request.GET, bir listie varmış gibi görünür :

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

Tamam Güncelleme: Son değeri döndürmek için tasarlandı, benim kullanım durumum bir listeye ihtiyacım var.

django belgelerinden:

QueryDict. getitem (anahtar) Verilen anahtarın değerini döndürür. Anahtar birden fazla değere sahipse getitem () son değeri döndürür. Anahtar yoksa django.utils.datastructures.MultiValueDictKeyError'ı oluşturur. (Bu, Python'un standart KeyError'ının bir alt sınıfıdır, böylece KeyError'ı yakalamaya devam edebilirsiniz.

QueryDict.getlist (key) Verileri istenen anahtarla Python listesi olarak döndürür. Anahtar yoksa boş bir liste döndürür. Bir tür liste döndürmek garantilidir.

Güncelleme: Eğer django geliştiricinin bunu neden yaptığını bilen biri varsa lütfen bana bildirin, bir liste göstermek mantıksız görünüyor ve liste gibi davranmıyor. Pek pitonik değil!


4
Bence mantık, bir liste mi yoksa bireysel bir değer mi bekleyeceğinizi bilmeniz gerektiğidir. QueryDict.getitem bazen bir liste, bazen de tek bir öğe döndürmemelidir - o zaman herkesin düzgün bir şekilde işlemek için dönüş türünü her zaman kontrol etmesi gerekir.
jgiles

Yanıtlar:


181

GET nesnesinin getlist () işlevini istiyorsunuz :

request.GET.getlist('myvar')

10
Öğeleri geri göndermek için jquery kullanıyorsanız, var adının sonuna bir "[]" eklemeniz gerekebilir.
Danny Staple

2
Getlist'i biliyordum ama "[]" beni attı. Ayrıca Andy Staple adında bir arkadaşım var ve bir an için Django hakkında benim sandığımdan çok daha fazlasını bildiğini düşündüm. Bu beni de attı.
kungphu

1
Bunun Django belgelerinin her yerine, Django Rest Framework belgelerine ve alnıma geriye doğru postalanması gerekiyor. Bu beni gerçekten hazırlıksız yakaladı
Anthony Manning-Franklin

Görünüşe göre Django topu bunun üzerine düşürmüş gibi görünüyor, kasıtlı olup olmadığından emin değil
NaturalBornCamper

1

Diğer bir çözüm, istek nesnesinin bir kopyasını oluşturmaktır ... Normalde bir request.GET veya request.POST nesnesi üzerinden yineleme yapamazsınız, ancak kopya üzerinde bu tür işlemleri yapabilirsiniz:

res_set = request.GET.copy()
for item in res_set['myvar']:
    item
...

2
Emin misiniz? bu benim için QueryDict'in davranışını değiştirmez. ben sadece aynı "sınırlama" ile başka QueryDict olsun
fındık

0

Aynı parametre için birden çok değer içeren (bir dizi onay kutusu gibi) bir QueryDict nesnesinden bir sorgu dizesi oluştururken urlencode () yöntemini kullanın:

Örneğin, gelen sorgu isteğini almam, bir parametreyi kaldırmam ve güncellenmiş sorgu dizesini sonuç sayfasına döndürmem gerekiyordu.

# Obtain a mutable copy of the original string
original_query = request.GET.copy()

# remove an undesired parameter
if 'page' in original_query:
    del original_query['page']

Şimdi, orijinal sorgu aynı parametre için aşağıdaki gibi birden çok değere sahipse: {... 'track_id': ['1', '2'], ...} kodu kullanırken sorgu dizesindeki ilk öğeyi kaybedersiniz sevmek:

new_query = urllib.parse.urlencode(original_query)

sonuç ...

...&track_id=2&...

Ancak, birden çok değeri düzgün şekilde dahil etmek için QueryDict sınıfının urlencode yöntemi kullanılabilir:

new_query = original_query.urlencode()

hangi üretir ...

...&track_id=1&track_id=2&...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.