Чтобы использовать Turbolinks 5 с Django, как я могу автоматизировать включение заголовка Turbolinks-Location при использовании redirect()?

Согласно документации Turbolinks 5 для «Последующих перенаправлений» (https://github.com/turbolinks/turbolinks#following-redirects):

Когда вы посещаете местоположение /one, а сервер перенаправляет вас в местоположение /two, вы ожидаете, что адресная строка браузера отобразит перенаправленный URL-адрес.

Однако Turbolinks делает запросы, используя XMLHttpRequest, который прозрачно следует перенаправлениям. Turbolinks не может определить, привел ли запрос к перенаправлению, без дополнительного взаимодействия с сервером.

И решение для этого состоит в следующем:

отправить заголовок Turbolinks-Location в ответ на посещение, которое было перенаправлено, и Turbolinks заменит самую верхнюю запись истории браузера предоставленным вами значением.

Движок Turbolinks Rails автоматически выполняет эту оптимизацию для запросов XHR без GET, которые перенаправляют с помощью помощника redirect_to.

Я очень заинтересован в использовании Turbolinks в моем проекте Django (1.11), и мне интересно, может ли кто-нибудь указать мне правильное направление, как создать новую функцию Django redirect() или изменить существующую, чтобы всегда включать Turbolinks -Заголовок Location, который необходим для того, чтобы перенаправления функционировали должным образом. Я определенно не хочу вручную устанавливать этот заголовок каждый раз, когда делаю перенаправление.

Аналогичная запись есть в разделе «Перенаправление после отправки формы» (https://github.com/turbolinks/turbolinks#redirecting-after-a-form-submission) Я также был бы признателен за любую помощь в понимании того, как реализовать:

Если отправка формы приводит к изменению состояния сервера, которое влияет на кешированные страницы, рассмотрите возможность очистки кеша Turbolinks с помощью Turbolinks.clearCache().

Движок Turbolinks Rails автоматически выполняет эту оптимизацию для запросов XHR без GET, которые перенаправляют с помощью помощника redirect_to.

Я видел, что на github есть пакет «Drop-in turbolinks для Django», но он разветвлен от turbolinks-classic, а в исходном коде нет упоминаний заголовка Turbolinks-Location, поэтому я уверен, что это не то, что я ищу .


person chrickso    schedule 11.11.2017    source источник


Ответы (2)


В конце концов я обнаружил, как сделать именно то, что я пытался, указав на кусок кода в этом проекте https://github.com/viewflow/django-material/blob/v2/material/middleware.py пользователем Reddit.

Я скопировал класс TurbolinksMiddleware в свой собственный middleware.py в каталоге приложений и перечислил его в моем settings.py как таковой.

# MIDDLEWARE CONFIGURATION
# --------------------------------------------------------------------------
MIDDLEWARE = [
    .
    .
    .
    'apps.middleware.TurbolinksMiddleware',
]

После обычного этапа установки, включающего turbolinks.js в мой html-шаблон, все работает правильно.

Вот класс TurbolinksMiddleware на случай, если он не будет доступен по ссылке выше:

class TurbolinksMiddleware(object):
    """
    Send the `Turbolinks-Location` header in response to a visit that was redirected,
    and Turbolinks will replace the browser’s topmost history entry .
    """

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

    def __call__(self, request):
        response = self.get_response(request)

        is_turbolinks = request.META.get('HTTP_TURBOLINKS_REFERRER')
        is_response_redirect = response.has_header('Location')

        if is_turbolinks:
            if is_response_redirect:
                location = response['Location']
                prev_location = request.session.pop('_turbolinks_redirect_to', None)
                if prev_location is not None:
                    # relative subsequent redirect
                    if location.startswith('.'):
                        location = prev_location.split('?')[0] + location
                request.session['_turbolinks_redirect_to'] = location
            else:
                if request.session.get('_turbolinks_redirect_to'):
                    location = request.session.pop('_turbolinks_redirect_to')
                    response['Turbolinks-Location'] = location
        return response
person chrickso    schedule 16.01.2018

Упомянутый вами пакет django реализует промежуточное ПО . который отвечает за добавление заголовков. Похоже, у старых турболинков заголовки назывались по-другому. Вы можете написать собственное промежуточное ПО для поддержки turbolinks 5.

Вместо обычной отправки форм отправьте их с помощью XHR.

Вы можете добиться этого с помощью простого django. Прочитайте док django CSRF - там подробно объясняется, что необходимо .

person dahrens    schedule 11.11.2017