การจับพารามิเตอร์ URL ในคำขอ GET


459

ขณะนี้ฉันกำลังกำหนดนิพจน์ทั่วไปเพื่อจับพารามิเตอร์ใน url ดังอธิบายในบทช่วยสอน ฉันจะเข้าถึงพารามิเตอร์จาก url เป็นส่วนหนึ่งของHttpRequestวัตถุได้อย่างไร HttpRequest.GETปัจจุบันฉันส่งคืนQueryDictวัตถุว่างเปล่า

ฉันต้องการเรียนรู้วิธีการทำสิ่งนี้โดยไม่ต้องมีห้องสมุดเพื่อให้ฉันได้รู้จัก Django ดีขึ้น

คำตอบ:


664

เมื่อ URL เป็นเหมือน:domain/search/?q=haharequest.GET.get('q', '')แล้วคุณจะใช้

qเป็นพารามิเตอร์ที่คุณต้องการและ''เป็นค่าเริ่มต้นหากqไม่พบ

อย่างไรก็ตามหากคุณเพียงแค่กำหนดค่าของคุณแทนการURLconfดักจับจากregexจะถูกส่งไปยังฟังก์ชันเป็นอาร์กิวเมนต์ (หรืออาร์กิวเมนต์ที่มีชื่อ)

เช่น:

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

จากนั้นviews.pyคุณก็จะมี

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

10
'? param =' เป็นวิธีเดียวที่ Django รู้จักพารามิเตอร์หรือไม่ มีวิธีใช้ URLconf กับ HTTP.GET หรือไม่ ฉันต้องการทำ / param / 2
sutee

3
ตรวจสอบส่วนที่สองของการตอบสนองของฉันเกี่ยวกับการจับภาพ URLconf และ regex ของคุณ
camflan

2
ไม่มีปัญหา. ใช้ request.GET หากคุณส่งแบบฟอร์มโดยใช้ GET ให้ใช้ request.POST หากคุณส่งแบบฟอร์มโดยใช้ POST และหากคุณต้องการกำหนดค่า URL ให้มีส่วนของตัวแปรก็เป็นอาร์กิวเมนต์ URLconf / view
camflan

10
สิ่งที่เกี่ยวกับมุมมองตามระดับ?
ผู้ใช้

8
สำหรับมุมมองตามระดับคุณสามารถใช้self.kwargs['parameter']
Royendgel Silberie

337

เพื่ออธิบายคำอธิบายของ camflan ให้สมมุติว่าคุณมี

  • กฎ url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • คำขอเข้ามาสำหรับ http://domain/user/thaiyoshi/?message=Hi

กฎตัวแจกจ่าย URL จะจับส่วนต่างๆของเส้นทาง URL (ที่นี่"user/thaiyoshi/") และส่งต่อไปยังฟังก์ชันมุมมองพร้อมกับวัตถุคำขอ

สตริงแบบสอบถาม (ที่นี่message=Hi) จะแยกกันและพารามิเตอร์จะถูกเก็บไว้เป็นในQueryDict request.GETไม่มีการจับคู่หรือการประมวลผลเพิ่มเติมสำหรับพารามิเตอร์ HTTP GET

ฟังก์ชั่นมุมมองนี้จะใช้ทั้งสองส่วนแยกจากเส้นทาง URL และพารามิเตอร์แบบสอบถาม:

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

ตามบันทึกข้างคุณจะพบวิธีการร้องขอ (ในกรณีนี้"GET"และสำหรับรูปแบบการแสดงความคิดเห็นโดยปกติ"POST") request.methodใน ในบางกรณีการตรวจสอบว่าตรงกับสิ่งที่คุณคาดหวังมีประโยชน์หรือไม่

อัปเดต:เมื่อตัดสินใจว่าจะใช้พา ธ URL หรือพารามิเตอร์เคียวรีเพื่อส่งข้อมูลสิ่งต่อไปนี้อาจช่วยได้:

  • ใช้เส้นทาง URL เพื่อระบุทรัพยากรที่ไม่ซ้ำเช่น/blog/post/15/(ไม่/blog/posts/?id=15)
  • ใช้พารามิเตอร์การสืบค้นเพื่อเปลี่ยนวิธีแสดงทรัพยากรเช่น/blog/post/15/?show_comments=1หรือ/blog/posts/2008/?sort_by=date&direction=desc
  • เพื่อทำให้ URL ที่เป็นมิตรกับมนุษย์หลีกเลี่ยงการใช้หมายเลข ID และใช้เช่นวันที่หมวดหมู่และ / หรือตัวบุ้ง: /blog/post/2008/09/30/django-urls/

17
นี่เป็นคำตอบที่เขียนได้ดีมาก มันช่วยให้ฉันเข้าใจ Django ดีขึ้นเล็กน้อย
Mark

2
เราจะรับค่าพารามิเตอร์ทั้งหมดได้อย่างไรโดยไม่ระบุชื่อ
numerah

@numerah Request.GET เป็นพจนานุกรม Python คุณสามารถทำซ้ำได้ผ่าน request.GET.items ()
akaihola

คำตอบที่สมบูรณ์แบบ
Jay Geeth

1
เหตุผลใดที่ทำให้ชอบติดตามพฤติกรรมที่เขียนในการอัปเดต (เมื่อใช้เส้นทาง URL เทียบกับ
Params

55

ใช้ GET

request.GET["id"]

ใช้ POST

request.POST["id"]

27
ในขณะที่ใช้งานได้กับคีย์ที่มีอยู่คำตอบของ camflan และ akaihola ได้ใช้. get () เพื่อหลีกเลี่ยงKeyErrorข้อยกเว้นในกรณีของคีย์ที่หายไป ก็ควรที่จะทำแบบเดียวกัน (เช่นrequest.POST.get('id', ''))
vastlysuperiorman


21

สำหรับสถานการณ์ที่คุณมีเพียงrequestวัตถุที่คุณสามารถใช้ได้request.parser_context['kwargs']['your_param']


2
สิ่งที่ฉันต้องการ ขอบคุณ
user4052054

20

ฉันต้องการเพิ่มตัวเลือกของตัวเองที่นี่ บางคนอาจสงสัยว่าจะกำหนดเส้นทางเป็น urls.py เช่น

domain/search/?q=CA

เพื่อให้เราสามารถเรียกใช้แบบสอบถาม

ความจริงก็คือไม่จำเป็นต้องตั้งค่าเส้นทางใน urls.py สิ่งที่คุณต้องตั้งค่าเป็นเพียงเส้นทางใน urls.py

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

และเมื่อคุณป้อนhttp: // servername: พอร์ต / โดเมน / search / q = CA ส่วนของแบบสอบถาม '? q = CA' จะถูกจองโดยอัตโนมัติในตารางแฮชซึ่งคุณสามารถอ้างอิงได้

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

นี่คือตัวอย่าง (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

นอกจากนี้เมื่อคุณเขียนสตริงแบบสอบถามใน Url

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

อย่าห่อสตริงแบบสอบถามในเครื่องหมายคำพูดเช่น

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

สวัสดีเอริค! ฉันใหม่กับ Django คุณช่วยเพิ่มความสว่างให้กับ "queryset = queryset.filter (state__name = state_name)" ได้ไหม เครื่องหมายขีดล่างคู่ใน state__name มีความหมายว่าอย่างไร
Subbu

1
ที่นี่ "รัฐ" เป็นตารางและ "ชื่อ" เป็นไฟล์ในตารางนี้ ในตัวกรองของ Django, state__name จะอ้างอิงค่าของฟิลด์ "ชื่อ" ในตาราง "สถานะ"
Eric Andrews

อันนี้ใช้ได้ผลกับคนอื่น
Sibish

17

ฉันต้องการแบ่งปันเคล็ดลับที่อาจช่วยคุณประหยัดเวลา
หากคุณวางแผนที่จะใช้สิ่งนี้ในurls.pyไฟล์ของคุณ:

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

www.example.com/<username>ซึ่งโดยทั่วไปหมายถึง อย่าลืมวางไว้ที่ส่วนท้ายของรายการ URL ของคุณเพราะไม่เช่นนั้นมีแนวโน้มที่จะทำให้เกิดความขัดแย้งกับรายการ URL ที่ตามมาด้านล่างเช่นการเข้าถึงหนึ่งในรายการเหล่านั้นจะทำให้คุณมีข้อผิดพลาด: User matching query does not exist.

ฉันเพิ่งพบตัวเอง หวังว่ามันจะช่วย!


2
นอกจากนี้ในกรณีนี้คุณอาจต้องการตรวจสอบว่าชื่อผู้ใช้ไม่ได้ชนกับ URL อื่น ๆ
DrKaoliN

13

คุณมีวิธีการทั่วไปสองวิธีในกรณีที่ URL ของคุณมีลักษณะดังนี้:

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

v1:

หากจำเป็นต้องใช้รหัสเฉพาะคุณสามารถใช้:

key_a = request.GET['a']

สิ่งนี้จะคืนค่าaถ้ามีคีย์และมีข้อยกเว้นถ้าไม่

v2:

หากคีย์ของคุณเป็นตัวเลือก:

request.GET.get('a')

คุณสามารถลองได้โดยไม่ต้องมีข้อโต้แย้งใด ๆ นี้จะไม่ผิดพลาด เพื่อให้คุณสามารถห่อด้วยtry: except:และกลับมาเป็นHttpResponseBadRequest()ตัวอย่าง นี่เป็นวิธีที่ง่ายในการทำให้โค้ดของคุณซับซ้อนน้อยลงโดยไม่ต้องใช้การจัดการข้อยกเว้นพิเศษ


ฉันจะตรวจสอบพารามิเตอร์การสืบค้นจากเทมเพลตได้อย่างไร
Akin Hwan


5

แบบสอบถามเหล่านี้จะทำในสองวิธี หากคุณต้องการเข้าถึงพารามิเตอร์เคียวรี (GET) คุณสามารถเคียวรีต่อไปนี้:

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

หากคุณต้องการเข้าถึงพารามิเตอร์ที่ส่งผ่านโดย POST คุณจะต้องเข้าถึงวิธีนี้:

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

การเข้าถึงพจนานุกรม (QueryDict) ด้วย 'รับ ()' คุณสามารถตั้งค่าเริ่มต้น ในกรณีข้างต้นหากไม่ได้รับแจ้ง 'สถานะ' หรือ 'บทบาท' ค่าจะเป็นไม่มี


0

นี่เป็นอีกหนึ่งโซลูชันทางเลือกที่สามารถนำไปใช้ได้

ในการกำหนดค่า URL :

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

ในมุมมอง:

list2 = queryparams.split("&")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.