Есть ли способ получить ссылочный URL-адрес через пользовательский заголовок HTTP? - PullRequest
8 голосов
/ 10 января 2020

В настоящее время я использую следующую функцию для получения ссылочного представления:

def get_referer_view(request, default=None):   
    referer = request.META.get('HTTP_REFERER')
    if not referer:
        return default

    # remove the protocol and split the url at the slashes
    referer = re.sub('^https?:\/\/', '', referer).split('/')
    if referer[0] != request.META.get('SERVER_NAME'):
        return default

    # add the slash at the relative path's view and finished
    referer = u'/' + u'/'.join(referer[1:])
    return referer

Если я перенаправил view в результате программирования c logi c, например ..

return HttpResponseRedirect('dashboard')

... есть ли способ получить ссылочный вид без использования HTTP_REFERER, чтобы я мог использовать эту переменную в перенаправленном view? Это не всегда устанавливается в заголовках браузера.

Обратите внимание, поскольку представления перенаправляются программно, я не могу использовать POST для сбора данных.

Возможно, можно как-то установить и получить пользовательский заголовок?

Ответы [ 3 ]

2 голосов
/ 16 января 2020

Используйте компонент промежуточного программного обеспечения Django.

https://docs.djangoproject.com/en/3.0/topics/http/middleware/

Примерно так должно работать:

class HTTPReferer:

    def __init__(self, get_response):
        self.get_response = get_response

def __call__old(self, request):
    # old
    referer = request.META.get('HTTP_REFERER', None)
    request.referer = referer
    # other business logic as you like it
    response = self.get_response(request)
    return response

def __call__(self, request):
    # reflecting last edit
    path = request.path
    response = self.get_response(request)
    response['previous_path'] = path
    return response

Так что вы может ie любая информация, необходимая для каждого цикла запроса / ответа, в Django (вы также можете установить пользовательские заголовки и т. д. c ...)

В приведенном выше примере HTTP_REFERER будет Доступен в объекте запроса как referer.

РЕДАКТИРОВАТЬ: Я думаю, вы обеспокоены тем, что HTTP_REFERER не всегда заполняется клиентом; так что вы могли бы ie HttpRequest.path для каждого запроса к пользовательскому заголовку. Если путь недостаточен, вы также можете сохранить аргументы запроса. Вот и все, я думаю. Затем у вас есть собственный заголовок, заполненный последним путем. Далее, если этого недостаточно, вы можете использовать Django URL resolver .

1 голос
/ 22 января 2020

Так как вы управляете страницей, делающей запрос, обязательно. Добавьте текущий URL к какому-либо заголовку и извлеките его в своей функции, например: Добавить заголовок запроса перед перенаправлением

, поэтому вместо этого:

def current_view():
   ...
   return HttpResponseRedirect('dashboard')

do что-то вроде этого:

def current_view():
    ...
    response = redirect('/dashboard')
    response['source-view'] = request.resolver_match.view_name
    return response

Это должно привести к 302 с пользовательским заголовком source-view, который вы можете извлечь в получающем представлении

0 голосов
/ 07 февраля 2020

Для тех, кто заинтересован, вот решение, которое я получил. Хитрость заключается в том, чтобы установить повара ie после первого запроса на сохранение view_name или path, а затем вызвать его и сохранить в request перед отображением представления.

class MyMiddleware:

    def __init__(self, get_response):
        # One-time configuration and initialization.
        self.get_response = get_response

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        # Add the referer cookie be accessible in request.response
        request.referer_view = request.COOKIES.get('referer_view', None)
        request.referer_path = request.COOKIES.get('referer_path', None)
        print('request.referer_view', request.referer_view)
        print('request.referer_path', request.referer_path)

        response = self.get_response(request)
        # Code to be executed for each request/response after
        # the view is called.

        # Set a cookie with the current view name that is cleared each time the view changes
        response.set_cookie('referer_view', request.resolver_match.view_name)
        response.set_cookie('referer_path', request.path)

        return response

Затем значения обновляются в этом цикле каждый раз, когда изменяется представление.

...