Как я могу получить все заголовки запроса в Django? - PullRequest
90 голосов
/ 08 октября 2010

Мне нужно получить все заголовки запросов Django.Из того, что я прочитал, Django просто сбрасывает все в переменную request.META вместе со многими другими данными.Как лучше всего получить все заголовки, которые клиент отправил в мое приложение Django?

Я собираюсь использовать их для создания httplib запроса.

Ответы [ 8 ]

121 голосов
/ 08 октября 2010

Согласно документации request.META - это «стандартный словарь Python, содержащий все доступные заголовки HTTP». Если вы хотите получить все заголовки, вы можете просто перебрать словарь.

Какая часть вашего кода для этого зависит от ваших конкретных требований. Любое место, которое имеет доступ к request, должно это сделать.

Обновление

Мне нужен доступ к нему в классе Middleware, но когда я перебираю его, я получаю много значений, кроме заголовков HTTP.

Из документации:

За исключением CONTENT_LENGTH и CONTENT_TYPE, как указано выше, любые заголовки HTTP в запросе преобразуются в ключи META путем преобразования всех символов в верхний регистр, замены любых дефисов подчеркиванием и добавление префикса HTTP_ к имени .

(выделение добавлено)

Чтобы получить только заголовки HTTP, просто отфильтруйте по ключам с префиксом HTTP_.

Обновление 2

Не могли бы вы показать мне, как я могу построить словарь заголовков, отфильтровывая все ключи из переменной request.META, которые начинаются с HTTP_ и удаляют ведущую часть HTTP_.

Конечно. Вот один из способов сделать это.

import re
regex = re.compile('^HTTP_')
dict((regex.sub('', header), value) for (header, value) 
       in request.META.items() if header.startswith('HTTP_'))
17 голосов
/ 23 января 2012

Это еще один способ сделать это, очень похожий на ответ Manoj Govindan выше:

import re
regex_http_          = re.compile(r'^HTTP_.+$')
regex_content_type   = re.compile(r'^CONTENT_TYPE$')
regex_content_length = re.compile(r'^CONTENT_LENGTH$')

request_headers = {}
for header in request.META:
    if regex_http_.match(header) or regex_content_type.match(header) or regex_content_length.match(header):
        request_headers[header] = request.META[header]

Это также захватит заголовки запросов CONTENT_TYPE и CONTENT_LENGTHвместе с HTTP_.request_headers['some_key] == request.META['some_key'].

Изменить соответствующим образом, если вам нужно включить / не включить определенные заголовки.Django перечисляет группу, но не все, здесь: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Алгоритм Django для заголовков запросов:

  1. Заменить дефис - с подчеркиванием _
  2. Преобразовать в UPPERCASE.
  3. Добавить HTTP_ ко всем заголовкам в исходном запросе, кроме CONTENT_TYPE и CONTENT_LENGTH.

Значения каждого заголовка должны бытьнеизмененной.

11 голосов
/ 01 апреля 2019

Начиная с Django 2.2, вы можете использовать request.headers для доступа к заголовкам HTTP. Из документации по HttpRequest.headers :

Нечувствительный к регистру, подобный dict объект, который обеспечивает доступ ко всем заголовкам с префиксом HTTP (плюс Content-Length и Content-Type) из запроса.

Имя каждого заголовка стилизовано с помощью заголовка (например, User-Agent), когда оно отображается. Вы можете получить доступ к заголовкам без учета регистра:

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> 'User-Agent' in request.headers
True
>>> 'user-agent' in request.headers
True

>>> request.headers['User-Agent']
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers['user-agent']
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get('User-Agent')
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get('user-agent')
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

Чтобы получить все заголовки, вы можете использовать request.headers.keys() или request.headers.items().

5 голосов
/ 17 сентября 2017

request.META.get ('HTTP_AUTHORIZATION') /python3.6/site-packages/rest_framework/authentication.py

вы можете получить это из этого файла, хотя ...

4 голосов
/ 08 октября 2010

Не думаю, что есть простой способ получить только заголовки HTTP. Вы должны перебрать request.META dict, чтобы получить то, что вам нужно.

django-debug-toolbar использует тот же подход для отображения информации заголовка. Взгляните на этот файл , отвечающий за получение информации заголовка.

0 голосов
/ 13 марта 2019

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

from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from apps.authentication.models import CerebroAuth

class CerebroAuthentication(BaseAuthentication):
def authenticate(self, request):
    client_id = request.META.get('HTTP_AUTHORIZATION')
    if not client_id:
        raise exceptions.AuthenticationFailed('Client key not provided')
    client_id = client_id.split()
    if len(client_id) == 1 or len(client_id) > 2:
        msg = ('Invalid secrer key header. No credentials provided.')
        raise exceptions.AuthenticationFailed(msg)
    try:
        client = CerebroAuth.objects.get(client_id=client_id[1])
    except CerebroAuth.DoesNotExist:
        raise exceptions.AuthenticationFailed('No such client')
    return (client, None)
0 голосов
/ 18 апреля 2017
<b>request.META</b><br>
{% for k_meta, v_meta in request.META.items %}
  <code>{{ k_meta }}</code> : {{ v_meta }} <br>
{% endfor %}
0 голосов
/ 17 января 2017

Похоже, вы намереваетесь использовать входящий HTTP-запрос для формирования другого HTTP-запроса.Вроде как ворота.Существует отличный модуль django-revproxy , который выполняет именно это.

Источник - довольно хороший справочник о том, как выполнить то, что вы пытаетесь сделать.

...