Захват параметров URL в request.GET

В настоящее время я определяю регулярные выражения для захвата параметров в URL-адресе, как описано в учебнике. Как мне получить доступ к параметрам из URL-адреса в качестве части объекта HttpRequest? Мой HttpRequest.GET в настоящее время возвращает пустой объект QueryDict.

Я хотел бы узнать, как это сделать без библиотеки, чтобы лучше узнать Django.

Ответ 1

Когда 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

Ответ 2

Чтобы пояснить пояснение camflan, предположим, что у вас есть

  • правило url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • a во входящем запросе для 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-адреса, избегать использования идентификационных номеров и использовать, например. даты, категории и/или пули: /blog/post/2008/09/30/django-urls/

Ответ 3

Использование GET

request.GET["id"]

Использование POST

request.POST["id"]

Ответ 4

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

Ответ 5

Я хотел бы поделиться советом, который может сэкономить вам некоторое время.
Если вы планируете использовать что-то вроде этого в вашем файле urls.py:

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

Что в основном означает www.example.com/<username>. Обязательно поместите его в конце ваших URL-записей, потому что в противном случае он подвержен конфликтам с последующими URL-адресами, то есть доступ к одному из них будет, даст вам приятную ошибку: User matching query does not exist.

Я только что испытал это сам; надеюсь, что это поможет!

Ответ 6

В ситуациях, когда у вас есть только объект request, вы можете использовать request.parser_context['kwargs']['your_param']

Ответ 7

У вас есть два общих способа сделать это, если ваш URL-адрес выглядит так:

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

v1:

Если конкретный ключ является обязательным, вы можете использовать:

key_a = request.GET['a']

Это вернет значение a, если ключ существует, и исключение, если нет.

v2:

Если ваши ключи не являются обязательными:

request.GET.get('a')

Вы можете попробовать это без каких-либо аргументов, это не сработает. Поэтому вы можете обернуть его с помощью try: except: и вернуть HttpResponseBadRequest() в пример. Это простой способ сделать ваш код менее сложным, не используя специальную обработку исключений.

Ответ 8

Это не совсем то, что вы просили, но этот фрагмент полезен для управления query_strings в templates.

Ответ 9

Я хотел бы добавить некоторые варианты себя, здесь. Кто-то хотел бы знать, как установить путь в urls.py, например,

domain/search/?q=CA

чтобы мы могли вызвать запрос.

Дело в том, что НЕ нужно устанавливать такой маршрут в urls.py. То, что вам нужно установить, это просто маршрут в urls.py

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

и когда вы вводите http://имя_сервера: порт/домен/поиск/? 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"

Ответ 10

Эти запросы в настоящее время выполняются двумя способами. Если вы хотите получить доступ к параметрам запроса (GET), вы можете запросить следующее:

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

Если вы хотите получить доступ к параметрам, переданным POST, вам нужно получить доступ к этому способу:

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

Получая доступ к словарю (QueryDict) с помощью get(), вы можете установить значение по умолчанию. В вышеупомянутых случаях, если "статус" или "роль" не сообщаются, значения равны None.