При обработке запроса POST в файле views.py Django мне иногда нужно перенаправить его на другой URL-адрес. Этот URL-адрес, на который я перенаправляюсь, обрабатывается другой функцией в том же файле Django views.py. Есть ли способ сделать это и сохранить исходные данные POST?
ОБНОВЛЕНИЕ: больше объяснений, почему я хочу это сделать. У меня есть два веб-приложения (назовем их AppA и AppB), которые принимают данные, введенные пользователем в текстовое поле. Когда пользователь нажимает кнопку «Отправить», данные обрабатываются и отображаются подробные результаты. AppA и AppB ожидают разных типов данных. Иногда пользователь по ошибке отправляет данные типа AppB в AppA. Когда это происходит, я хочу перенаправить их в AppB и показать результаты AppB или, по крайней мере, заполнить его данными, которые они ввели в AppA.
Также:
Клиенту нужно два отдельных приложения, а не объединять их в одно.
Я не могу показать код, поскольку он принадлежит клиенту.
ОБНОВЛЕНИЕ 2: Я решил, что KISS - лучший принцип здесь. Я объединил два приложения в одно, что упростило и повысило надежность; Я тоже смогу убедить клиента, что это лучший способ. Спасибо за отличный отзыв. Если бы я собирался поддерживать два приложения, как описано, я думаю, что сеансы были бы способом сделать это - спасибо Мэтью Дж. Моррисону за это. Спасибо Дзиде, так как его комментарии заставили меня задуматься о дизайне и упрощении.
id
GET, а также имеет доступ к другим данным, отправленным POST.Ответы:
Если вы столкнулись с такой проблемой, есть небольшая вероятность, что вам придется пересмотреть свой дизайн.
Это ограничение HTTP: данные POST не могут идти с перенаправлениями.
Можете ли вы описать, чего вы пытаетесь достичь, и, может быть, тогда мы подумаем о каком-нибудь изящном решении.
Если вы не хотите использовать сеансы, как предложил Мэтью, вы можете передать параметры POST в GET на новую страницу (рассмотрите некоторые ограничения, такие как безопасность и максимальная длина параметров GET в строке запроса).
ОБНОВЛЕНИЕ своего обновления :) Мне кажется странным, что у вас есть 2 веб-приложения, и эти приложения используют один views.py (я прав?). В любом случае рассмотрите возможность передачи ваших данных из POST в GET в правильное представление (если, конечно, данные не конфиденциальны).
источник
Я думаю, что, вероятно, я бы справился с этой ситуацией, если бы сохранить данные публикации в сеансе, а затем удалить их, когда они мне больше не нужны. Таким образом, я могу получить доступ к исходным данным сообщения после перенаправления, даже если этот пост исчез.
Будет ли это работать для того, что вы пытаетесь сделать?
Вот пример кода того, что я предлагаю: (имейте в виду, что это непроверенный код)
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
Еще одна вещь, о которой следует помнить ... если вы делаете это, а также загружаете файлы, я бы не стал делать это таким образом.
источник
Вам необходимо использовать временное перенаправление HTTP 1.1 (307).
К сожалению, Django
redirect()
иHTTPResponseRedirect
(постоянный) возвращают только 301 или 302. Вы должны реализовать это самостоятельно: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)
См. Также модуль django.http .
Редактировать:
в последних версиях Django измените
iri_to_uri
импорт на:from django.utils.encoding import iri_to_uri
источник
использовать
requests
пакет. его очень легко реализовать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Запросы
request.post
источник
Просто вызовите новое представление из старого представления, используя тот же объект запроса. Конечно, это не приведет к перенаправлению как таковому, но если все, что вас волнует, - это «перенос» данных из одного представления в другое, тогда это должно сработать.
Я протестировал следующий фрагмент, и он работает.
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
источник
Вы можете использовать рендер и контекст с ним:
Render(request,"your template path", {'vad name' : var value}
Вы можете получить вары в шаблоне:
источник
Недавно я столкнулся с подобной проблемой.
В основном у меня была форма A, после ее отправки появлялась другая форма B, которая содержит некоторые результаты + форму. После отправки B я хотел показать пользователю какое-то предупреждение и оставить пользователя только на B.
Я решил это, отобразив результаты в
<output>
поле в B.<output name="xyz" value="xyz">{{xyz}}</output>
И я использовал тот же вид для A-> B и B-> B. Теперь мне просто нужно было различать, исходит ли запрос от A или B, и обрабатывать соответственно.
def view1(request): if "xyz" in request.POST: # request from B # do some processing return render(request, 'page.html', {"xyz":request.POST["xyz"]}) else: # request from A res = foo() # some random function return render(request, 'page.html', {"xyz":res})
Но это работает, только если форма B маленькая и не такая динамичная.
источник
Если вы используете перенаправление после обработки 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, разве вас не беспокоит дублирование данных из-за обновления страницы пользователем?
источник
pk
новую запись при перенаправлении. # 2, сохраните данные вcache
серверной части и снова передайте ключ. # 3, сохраните его в сеансе. Любое из этих действий совершенно нормально для веб-приложения, даже если оно временное. Если данные формы нетривиально поддаются синтаксическому анализу, это также сделало бы систему быстрее, если бы вывод уже был кэширован.