Menangkap parameter url dalam permintaan.GET


458

Saat ini saya mendefinisikan ekspresi reguler untuk menangkap parameter dalam url, seperti yang dijelaskan dalam tutorial. Bagaimana cara mengakses parameter dari url sebagai bagianHttpRequest objek? HttpRequest.GETSaat ini saya mengembalikan QueryDictobjek kosong .

Saya ingin belajar bagaimana melakukan ini tanpa perpustakaan sehingga saya bisa mengenal Django lebih baik.

Jawaban:


662

Ketika url sepertidomain/search/?q=haha :, Maka Anda akan menggunakan request.GET.get('q', '').

qadalah parameter yang Anda inginkan, dan ''adalah nilai default jika qtidak ditemukan.

Namun, jika Anda hanya mengonfigurasi AndaURLconf , maka tangkapan Anda dari regexditeruskan ke fungsi sebagai argumen (atau argumen bernama).

Seperti:

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

Maka di Anda, views.pyAnda akan memiliki

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

10
Apakah '? Param =' satu-satunya cara Django mengenali parameter? Apakah ada cara untuk menggunakan URLconf dengan HTTP.GET? Saya ingin melakukan / param / 2.
sutee

3
Periksa bagian kedua dari tanggapan saya mengenai URLconf dan regex captures Anda.
camflan

2
Tidak masalah. gunakan request.GET jika Anda mengirimkan formulir menggunakan GET, gunakan request.POST jika Anda mengirimkan formulir menggunakan POST, dan jika Anda hanya ingin mengonfigurasi URL untuk memiliki bagian variabel, maka itu adalah argumen URLconf / view.
camflan

10
Bagaimana dengan tampilan berbasis kelas?
Pengguna

8
untuk tampilan berbasis kelas yang dapat Anda gunakanself.kwargs['parameter']
Royendgel Silberie

336

Untuk memperjelas penjelasan camflan, anggaplah Anda memilikinya

  • peraturan url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • a dalam permintaan masuk untuk http://domain/user/thaiyoshi/?message=Hi

Aturan operator URL akan menangkap bagian dari jalur URL (di sini "user/thaiyoshi/") dan meneruskannya ke fungsi tampilan bersama dengan objek permintaan.

String kueri (di sini message=Hi) diuraikan dan parameter disimpan sebagai QueryDictdalam request.GET. Tidak ada pencocokan atau pemrosesan lebih lanjut untuk parameter HTTP GET yang dilakukan.

Fungsi tampilan ini akan menggunakan kedua bagian yang diekstrak dari jalur URL dan parameter kueri:

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

Sebagai catatan tambahan, Anda akan menemukan metode permintaan (dalam hal ini "GET", dan untuk formulir yang dikirimkan biasanya "POST") di request.method. Dalam beberapa kasus, penting untuk memeriksa apakah cocok dengan yang Anda harapkan.

Pembaruan: Saat memutuskan apakah akan menggunakan jalur URL atau parameter kueri untuk meneruskan informasi, hal berikut dapat membantu:

  • gunakan jalur URL untuk sumber daya pengidentifikasi unik, mis. /blog/post/15/(tidak /blog/posts/?id=15)
  • gunakan parameter kueri untuk mengubah cara sumber ditampilkan, misalnya /blog/post/15/?show_comments=1atau/blog/posts/2008/?sort_by=date&direction=desc
  • untuk membuat URL yang ramah manusia, hindari menggunakan nomor ID dan gunakan mis. tanggal, kategori dan / atau siput: /blog/post/2008/09/30/django-urls/

17
Ini adalah jawaban yang ditulis dengan sangat baik. Itu benar-benar membantu saya memahami Django sedikit lebih baik.
Tandai

2
bagaimana kita bisa mendapatkan semua nilai parameter tanpa menyebutkan nama
numerah

@numerah request.GET adalah kamus Python. Anda dapat, misalnya, mengulang melalui request.GET.items ().
akaihola

jawaban sempurna.
Jay Geeth

1
alasan mengapa lebih disukai untuk mengikuti kebiasaan yang tertulis dalam pembaruan? (kapan harus menggunakan jalur URL vs GET params)
m0etaz

55

Menggunakan GET

request.GET["id"]

Menggunakan POST

request.POST["id"]

27
Meskipun ini berfungsi untuk kunci yang ada, jawaban oleh camflan dan akaihola telah menggunakan .get () untuk menghindari KeyErrorpengecualian dalam kasus kunci yang hilang. Akan bijaksana untuk melakukan hal yang sama (misalnya request.POST.get('id', '')).
extremelylysuperiorman

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

21

Untuk situasi di mana Anda hanya memiliki requestobjek yang dapat Anda gunakanrequest.parser_context['kwargs']['your_param']


2
Apa yang saya butuhkan. Terima kasih.
user4052054

20

Saya ingin menambahkan beberapa opsi sendiri, di sini. Seseorang akan bertanya-tanya bagaimana cara mengatur jalur di urls.py, seperti

domain/search/?q=CA

sehingga kami dapat meminta kueri.

Faktanya adalah bahwa TIDAK perlu mengatur rute seperti itu di urls.py. Yang perlu Anda atur hanyalah rute di urls.py

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

dan ketika Anda masukan http: // servername:? pelabuhan / domain / search / q = CA . Bagian permintaan '? Q = CA' akan secara otomatis dicadangkan di tabel hash yang dapat Anda rujuk

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

Berikut ini sebuah contoh (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

Selain itu, saat Anda menulis string kueri di Url

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

Jangan bungkus string kueri dalam tanda kutip, mis

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

Hai Eric! Saya baru mengenal Django. Bisakah Anda menjelaskan lebih lanjut tentang "queryset = queryset.filter (state__name = state_name)". Apa yang digandakan garis bawah dalam state__name.
Subbu

1
Di sini "negara" adalah tabel dan "nama" diajukan dalam tabel ini. Dalam filter Django, state__name akan referensi nilai bidang "nama" di tabel "negara".
Eric Andrews

ini bekerja dibandingkan dengan yang lain.
Sibish

17

Saya ingin berbagi tip yang dapat menghemat waktu Anda.
Jika Anda berencana menggunakan sesuatu seperti ini di urls.pyfile Anda :

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

Yang pada dasarnya berarti www.example.com/<username>. Pastikan untuk meletakkannya di akhir entri URL Anda, karena jika tidak, cenderung menyebabkan konflik dengan entri URL yang mengikuti di bawah ini, yaitu mengakses salah satu dari mereka akan memberi Anda kesalahan yang bagus: User matching query does not exist.

Saya baru saja mengalaminya sendiri; semoga membantu!


2
Plus, dalam hal ini Anda mungkin ingin memeriksa bahwa nama pengguna tidak bertabrakan dengan URL url lainnya.
DrKaoliN

13

Anda memiliki dua cara umum untuk melakukan itu jika url Anda terlihat seperti itu:

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

v1:

Jika kunci spesifik wajib Anda dapat menggunakan:

key_a = request.GET['a']

Ini akan mengembalikan nilai a jika ada kunci dan Pengecualian jika tidak.

v2:

Jika kunci Anda opsional:

request.GET.get('a')

Anda dapat mencobanya tanpa argumen apa pun ini tidak akan macet. Jadi Anda dapat membungkusnya dengan try: except:dan kembali HttpResponseBadRequest()dalam contoh. Ini adalah cara sederhana untuk membuat kode Anda lebih kompleks, tanpa menggunakan penanganan Pengecualian khusus.


bagaimana saya bisa mendeteksi param kueri dari templat?
Akin Hwan


5

Pertanyaan ini saat ini dilakukan dengan dua cara. Jika Anda ingin mengakses parameter kueri (GET) Anda dapat menanyakan hal-hal berikut:

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

Jika Anda ingin mengakses parameter yang dikirimkan oleh POST, Anda perlu mengakses cara ini:

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

Mengakses kamus (QueryDict) dengan 'get ()', Anda dapat menetapkan nilai default. Dalam kasus di atas, jika 'status' atau 'peran' tidak diinformasikan, nilainya adalah Tidak ada.


0

Ini adalah solusi alternatif lain yang dapat diterapkan:

dalam konfigurasi url. :

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

dalam pandangan:

list2 = queryparams.split("&")
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.