التقاط معلمات URL في request.GET
سؤال
أقوم حاليًا بتعريف التعبيرات العادية من أجل التقاط المعلمات في عنوان URL، كما هو موضح في البرنامج التعليمي.كيف يمكنني الوصول إلى المعلمات من عنوان url كجزء من ملف HttpRequest
هدف؟لي HttpRequest.GET
تقوم حاليا بإرجاع فارغة QueryDict
هدف.
أود أن أتعلم كيفية القيام بذلك بدون مكتبة حتى أتمكن من التعرف على جانغو بشكل أفضل.
المحلول
عندما يكون عنوان URL مثل: domain/search/?q=haha
، ثم يمكنك استخدامها request.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
نصائح أخرى
لتوضيح شرح 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
) يتم تحليلها ويتم تخزين المعلمات كـ a 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 صديقة للإنسان، تجنب استخدام أرقام المعرفات واستخدمها على سبيل المثال.التواريخ والفئات و/أو البزاقات:
/blog/post/2008/09/30/django-urls/
باستخدام الحصول على
request.GET["id"]
باستخدام البريد
request.POST["id"]
def some_view(request, *args, **kwargs):
if kwargs.get('q', None):
# Do something here ..
أود أن أشارككم نصيحة قد توفر لكم بعض الوقت.
إذا كنت تخطط لاستخدام شيء مثل هذا في urls.py
ملف:
url(r'^(?P<username>\w+)/$', views.profile_page,),
وهو ما يعني في الأساس www.example.com/<username>
.تأكد من وضعه في نهاية إدخالات URL الخاصة بك، وإلا فإنه قد يؤدي إلى حدوث تعارضات مع إدخالات URL التالية أدناه، على سبيل المثال:الوصول إلى واحد منهم سوف أعطيك الخطأ الجميل: User matching query does not exist.
لقد اختبرت ذلك بنفسي.نأمل أن يساعد!
في المواقف التي يكون لديك فيها فقط request
كائن يمكنك استخدامه request.parser_context['kwargs']['your_param']
لديك طريقتان شائعتان للقيام بذلك إذا كان عنوان URL الخاص بك يبدو هكذا:
https://domain/method/?a=x&b=y
الإصدار 1:
إذا كان المفتاح المحدد إلزاميًا، فيمكنك استخدام:
key_a = request.GET['a']
سيعود هذا بقيمة a
إذا كان المفتاح موجودًا واستثناء إذا لم يكن كذلك.
الإصدار الثاني:
إذا كانت مفاتيحك اختيارية:
request.GET.get('a')
يمكنك تجربة ذلك دون أي حجة، ولن يتعطل هذا.حتى تتمكن من لفها try: except:
والعودة HttpResponseBadRequest()
في المثال.هذه طريقة بسيطة لجعل التعليمات البرمجية الخاصة بك أقل تعقيدًا، دون استخدام معالجة الاستثناءات الخاصة.
ليس هذا بالضبط ما طلبته، ولكن هذا المقتطف مفيد للإدارة query_strings
في templates
.
أود أن أضيف بعض الخيارات بنفسي هنا.قد يتساءل شخص ما عن كيفية تعيين المسار في urls.py، مثل
domain/search/?q=CA
حتى نتمكن من استدعاء الاستعلام.
الحقيقة هي أنه ليس من الضروري تعيين مثل هذا المسار في urls.py.ما تحتاج إلى تعيينه هو فقط المسار الموجود في urls.py
urlpatterns = [
path('domain/search/', views.CityListView.as_view()),
]
وعندما تدخل http://servername:port/domain/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"