Django: Как перенаправить сообщение и передать данные сообщения
При обработке запроса POST в файле views.py Django мне иногда нужно перенаправить его на другой URL-адрес. Этот URL-адрес, к которому я перенаправляюсь, обрабатывается другой функцией в том же файле Django views.py. Есть ли способ сделать это и сохранить исходные данные POST?
UPDATE: больше объяснений, почему я хочу это сделать.
У меня есть два веб-приложения (позвоните им AppA и AppB), которые принимают данные, введенные пользователем в текстовое поле. Когда пользователь нажимает кнопку "Отправить", данные обрабатываются и отображаются подробные результаты. AppA и AppB ожидают различные типы данных. Иногда пользователь ошибочно записывает данные типа AppB в AppA. Когда это произойдет, я хочу перенаправить их в AppB и показать результаты AppB или, по крайней мере, заполнить данные, которые они ввели в AppA.
также:
-
Клиент хочет использовать два отдельных приложения, а не комбинировать их только с одним.
-
Я не могу показать код, как он принадлежит клиенту.
ОБНОВЛЕНИЕ 2:
Я решил, что KISS - лучший принцип здесь. Я объединил два приложения в одном, что делает вещи более простыми и надежными; Я должен быть в состоянии убедить клиента, что это лучший способ пойти тоже. Спасибо за отличную обратную связь. Если бы я собирался поддерживать два приложения, как описано, я думаю, что сеансы будут способом сделать это - благодаря Мэтью Дж. Моррисону за это. Благодаря Dzida, поскольку его комментарии заставили меня задуматься о дизайне и упрощении.
Ответы
Ответ 1
Если вы столкнулись с такой проблемой, есть небольшая вероятность, что вам, возможно, придется пересмотреть свои проекты.
Это ограничение HTTP, при котором данные POST не могут пересылаться с помощью перенаправления.
Можете ли вы описать, что вы пытаетесь выполнить, и, возможно, тогда мы сможем подумать о каком-то опрятном решении.
Если вы не хотите использовать сеансы, как предположил Мэтью, вы можете передать параметры POST в GET на новую страницу (рассмотрите некоторые ограничения, такие как безопасность и максимальная длина параметров GET в строке запроса).
ОБНОВЛЕНИЕ к вашему обновлению:)
Мне кажется странным, что у вас есть 2 веб-приложения, и эти приложения используют один view.py(я прав?). В любом случае, рассмотрите возможность передачи ваших данных из POST в GET в соответствующее представление (в случае, если данные не чувствительны, конечно).
Ответ 2
Я думаю, что, вероятно, я бы справился с этой ситуацией: сохранить данные в сеансе, а затем удалить, когда мне это больше не нужно. Таким образом, я могу получить доступ к исходным данным после перенаправления, даже если это сообщение ушло.
Будет ли это работать на то, что вы пытаетесь сделать?
Вот пример кода, который я предлагаю: (помните, что это непроверенный код)
def some_view(request):
#do some stuff
request.session['_old_post'] = request.POST
return HttpResponseRedirect('next_view')
def next_view(request):
old_post = request.session.get('_old_post')
#do some stuff using old_post
Еще одна вещь, о которой нужно помнить... если вы делаете это, а также загружаете файлы, я бы так не сделал.
Ответ 3
Вам нужно использовать HTTP 1.1 Temporary Redirect (307). К сожалению, django redirect() и HTTPResponse (Permanent) Redirect возвращают только 301 или 302. (см. модуль django.http)
Вы должны реализовать его самостоятельно:
from django.http import HttpResponse, iri_to_uri
class HttpResponseTemporaryRedirect(HttpResponse):
status_code = 307
def __init__(self, redirect_to):
HttpResponse.__init__(self)
self['Location'] = iri_to_uri(redirect_to)
Ответ 4
использовать requests
package.It очень легко реализовать
pip install requests
то вы можете вызывать любые URL-адреса любым способом и передавать данные
в ваших запросах импорта запросов
import requests
чтобы опубликовать данные, следуйте формату
r = requests.post('http://yourdomain/path/', data = {'key':'value'})
чтобы получить абсолютный url в представлении django, используйте
request.build_absolute_uri(reverse('view_name'))
Таким образом, код представления django выглядит как
r = requests.post(
request.build_absolute_uri(reverse('view_name')),
data = {'key':'value'}
)
где r
- объект ответа с атрибутами status_code
и content
.
r.status_code
указывает код состояния (при успехе - 200), а r.content
- тело ответа. Существует json-метод (r.json()
), который преобразует ответ в формат json
requests
request.post
Ответ 5
Просто вызовите новый вид из старого представления, используя тот же объект запроса.
Конечно, это не приведет к переадресации как таковой, но если все, о чем вы заботитесь, это "передача" данных из одного представления в другое, тогда оно должно работать.
Я протестировал следующий фрагмент, и он работает.
from django.views.generic import View
class MyOldView(View):
def post(self, request):
return MyNewView().post(request)
class MyNewView(View):
def post(self, request):
my_data = request.body
print "look Ma; my data made it over here:", my_data
Ответ 6
Если вы используете перенаправление после обработки POST до AppB
, вы можете избежать вызова метода AppB
из метода AppA
.
Пример:
def is_appa_request(request):
## do some magic.
return False or True
is_appb_request = is_appa_request
def AppA(request):
if is_appb_request(request):
return AppB(request)
## Process AppA.
return HttpResponseRedirect('/appa/thank_you/')
def AppB(request):
if is_appa_request(request):
return AppA(request)
## Process AppB.
return HttpResponseRedirect('/appb/thank_you/')
Это должно обеспечить прозрачный опыт для конечного пользователя, и клиент, который нанял вас, скорее всего, никогда не узнает разницу.
Если вы не перенаправляете после POST, вы не беспокоитесь о дублированных данных из-за обновления пользователем страницы?
Ответ 7
Вы можете использовать визуализировать и контекст с помощью:
Render(request,"your template path", {'vad name' : var value}
Вы можете получить vars в шаблоне:
{% If var name %}
{{ var name }}
{% endif %}