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.

sutee
sumber

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
camflan
sumber
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/
akaihola
sumber
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"]
Dadaso Zanzane
sumber
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 ..
Kevin
sumber
21

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

Ole Henrik Skogstrøm
sumber
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"
Eric Andrews
sumber
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!

DrKaoliN
sumber
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.

Bartłomiej
sumber
bagaimana saya bisa mendeteksi param kueri dari templat?
Akin Hwan
8

Ini bukan apa yang Anda minta, tapi potongan ini sangat membantu untuk mengelola query_stringsdi templates.

kemacetan
sumber
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.

mdcg
sumber
0

Ini adalah solusi alternatif lain yang dapat diterapkan:

dalam konfigurasi url. :

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

dalam pandangan:

list2 = queryparams.split("&")
sachi
sumber