İstekte URL parametrelerini yakalama.


459

Şu anda öğreticide açıklandığı gibi, bir url'deki parametreleri yakalamak için düzenli ifadeler tanımlıyorum. HttpRequestNesnenin bir parçası olarak URL'den parametrelere nasıl erişirim ? Benim HttpRequest.GETşu anda boş döner QueryDictnesne.

Django'yu daha iyi tanımak için bunu bir kütüphane olmadan nasıl yapacağımı öğrenmek istiyorum.

Yanıtlar:


664

Url gibi:,domain/search/?q=haha o zaman kullanabilirsiniz request.GET.get('q', '').

qistediğiniz parametredir ve bulunmazsa ''varsayılan değerdir q.

Ancak, bunun yerine sadece yapılandırıyorsanızURLconf , o zaman gelen yakalar regexişlevi argümanlar (veya adlandırılmış argümanlar) olarak geçirilir.

Gibi:

(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),

Sonra senin içinde views.pyolurdu

def profile_page(request, username):
    # Rest of the method

10
Django'nun parametreleri tanımasının tek yolu '? Param =' mı? URLconf'u HTTP.GET ile kullanmanın bir yolu var mı? / Param / 2 yapmak istiyorum.
sutee

3
URL bağlantınız ve normal ifade yakalamalarınızla ilgili yanıtımın ikinci bölümünü kontrol edin.
camflan

2
Sorun değil. GET kullanarak bir form gönderirseniz request.GET öğesini kullanın, POST kullanarak bir form gönderirseniz ve URL'leri yalnızca değişken bölümlere sahip olacak şekilde yapılandırmak istiyorsanız, bu bir URLconf / view argümanıdır.
camflan

10
Sınıfa dayalı görüşler ne olacak?
Kullanıcı

8
sınıf tabanlı görüntülemeler içinself.kwargs['parameter']
Royendgel Silberie

337

Camflan'ın açıklamasını netleştirmek için varsayalım

  • kural url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • için gelen bir istek http://domain/user/thaiyoshi/?message=Hi

URL dağıtıcı kuralı, URL yolunun (burada "user/thaiyoshi/") bazı kısımlarını yakalar ve bunları istek nesnesiyle birlikte görünüm işlevine iletir.

Sorgu dizesi (burada message=Hi) ayrıştırılır ve parametreler olarak saklanır QueryDictin request.GET. HTTP GET parametreleri için başka bir eşleştirme veya işleme yapılmaz.

Bu görünüm işlevi, URL yolundan çıkarılan parçaları ve bir sorgu parametresini kullanır:

def profile_page(request, username=None):
    user = User.objects.get(username=username)
    message = request.GET.get('message')

Yan not olarak, istek yöntemini (bu durumda "GET"ve genellikle gönderilen formlar için "POST") içinde bulabilirsiniz request.method. Bazı durumlarda, beklediğinizle eşleşip eşleşmediğini kontrol etmek yararlı olur.

Güncelleme: Bilgi aktarmak için URL yolunu veya sorgu parametrelerini kullanıp kullanmayacağınıza karar verirken aşağıdakiler yardımcı olabilir:

  • kaynakları benzersiz şekilde tanımlamak için URL yolunu kullanın, ör. /blog/post/15/(değil /blog/posts/?id=15)
  • Kaynak görüntülenme şeklini değiştirmek için sorgu parametreleri kullanmak, örneğin /blog/post/15/?show_comments=1veya/blog/posts/2008/?sort_by=date&direction=desc
  • insan dostu URL'ler oluşturmak için kimlik numaralarını kullanmaktan kaçının ve örneğin tarihler, kategoriler ve / veya sümüklü böcekler kullanın: /blog/post/2008/09/30/django-urls/

17
Bu gerçekten iyi yazılmış bir cevap. Elbette Django'yu biraz daha iyi anlamama yardımcı oldu.
Mark

2
isimlerden bahsetmeden tüm parametre değerlerini nasıl alabiliriz
numerah

@numerah request.GET bir Python sözlüğüdür. Örneğin request.GET.items () ile yineleme yapabilirsiniz.
akaihola

mükemmel cevap.
Jay Geeth

1
Güncellemede yazılan alışkanlıkları takip etmenin tercih edilmesinin bir nedeni var mı? (URL yolu ne zaman GET parametrelerine karşı kullanılır)
m0etaz

55

GET kullanma

request.GET["id"]

POST kullanma

request.POST["id"]

27
Bu, mevcut anahtarlar için çalışırken, camflan ve akaihola tarafından verilen cevaplar, KeyErroreksik anahtar durumunda istisnaları önlemek için .get () yöntemini kullanmıştır . Aynı şeyi yapmak akıllıca olur (örneğin request.POST.get('id', '')).
vastlysuperiorman

26
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..

21

Yalnızca requestkullanabileceğiniz nesneye sahip olduğunuz durumlar içinrequest.parser_context['kwargs']['your_param']


2
Tam olarak ihtiyacım olan şey. Teşekkürler.
user4052054

20

Buraya kendime bir seçenek eklemek istiyorum. Birisi urls.py dosyasında yolun nasıl ayarlanacağını merak eder.

domain/search/?q=CA

böylece sorguyu çağırabiliriz.

Gerçek şu ki, urls.py'de böyle bir rota ayarlamanız gerekli DEĞİLDİR. Ayarlamanız gereken şey sadece urls.py

urlpatterns = [
    path('domain/search/', views.CityListView.as_view()),
]

ve http: // sunucuadı: port / domain / search /? q = CA girdiğinizde . '? Q = CA' sorgu kısmı otomatik olarak rezerve edebileceğiniz karma tabloda ayrılacaktır.

request.GET.get('q', None).

İşte bir örnek (views.py)

class CityListView(generics.ListAPIView):
    serializer_class = CityNameSerializer

    def get_queryset(self):
        if self.request.method == 'GET':
            queryset = City.objects.all()
            state_name = self.request.GET.get('q', None)
            if state_name is not None:
                queryset = queryset.filter(state__name=state_name)
            return queryset

Ayrıca, URL'de sorgu dizesi yazdığınızda

http://servername:port/domain/search/?q=CA

Sorgu dizesini tırnak içine almayın, ör.

http://servername:port/domain/search/?q="CA"

Merhaba Eric! Django'da yeniyim. "Queryset = queryset.filter (durum_adı = durum_adı)" konusuna daha fazla ışık tutabilir misiniz? State__name'deki çift alt çizgi ne anlama gelir.
Subbu

1
Burada "state" bir tablodur ve "name" bu tabloda dosyalanmıştır. Django filtresinde state__name, "state" tablosundaki "name" alanının değerine başvurur.
Eric Andrews

bu diğerlerine göre çalıştı.
Sibirya

17

Size zaman kazandırabilecek bir ipucu paylaşmak istiyorum. Dosyanızda
böyle bir şey kullanmayı planlıyorsanız urls.py:

url(r'^(?P<username>\w+)/$', views.profile_page,),

Bu temel olarak www.example.com/<username>. , Aşağıda izleyin URL girişlerle neden çatışmalara maruz kalmıştır, çünkü aksi halde URL Girişlerin sonunda yerleştirmek için emin olun, onlardan yani erişimde bulunan bir olacak size güzel hata vermek: User matching query does not exist.

Ben de bunu kendim yaşadıysanız; Umarım yardımcı olur!


2
Ayrıca, bu durumda kullanıcı adlarının diğer URL girişleriyle çarpışmadığını kontrol etmek isteyebilirsiniz.
DrKaoliN

13

URL'nizin böyle görünmesi durumunda bunu yapmanın iki yaygın yolu vardır:

https://domain/method/?a=x&b=y

v1:

Belirli bir anahtarın zorunlu olması durumunda şunları kullanabilirsiniz:

key_a = request.GET['a']

Bu, aanahtar varsa bir değer ve yoksa bir İstisna döndürür .

v2:

Anahtarlarınız isteğe bağlıysa:

request.GET.get('a')

Herhangi bir tartışma olmadan bunun çökmeyeceğini deneyebilirsiniz. Böylece onu silebilir try: except:ve HttpResponseBadRequest()örnek olarak geri dönebilirsiniz . Bu, Özel İstisna işlemleri kullanmadan kodunuzu daha az karmaşık hale getirmenin basit bir yoludur.


sorgu parametresini şablondan nasıl tespit edebilirim?
Akın Hwan

8

Bu ne için sorulan tam olarak değil, ama bu pasajı yönetmek için yararlıdır query_stringsiçinde templates.


5

Bu sorgular şu anda iki şekilde yapılmaktadır. Sorgu parametrelerine (GET) erişmek istiyorsanız aşağıdakileri sorgulayabilirsiniz:

http://myserver:port/resource/?status=1
request.query_params.get('status', None) => 1

POST tarafından iletilen parametrelere erişmek istiyorsanız, şu şekilde erişmeniz gerekir:

request.data.get('role', None)

Sözlüğe (QueryDict) 'get ()' ile erişerek varsayılan bir değer ayarlayabilirsiniz. Yukarıdaki durumlarda, 'durum' veya 'rol' bildirilmezse, değerler Yok'tur.


0

Bu, uygulanabilecek başka bir alternatif çözümdür:

url yapılandırmasında. :

urlpatterns = [path('runreport/<str:queryparams>', views.get)]

görünümlerde:

list2 = queryparams.split("&")
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.