Подтвердить что ты не робот

Django: Как перенаправить сообщение и передать данные сообщения

При обработке запроса POST в файле views.py Django мне иногда нужно перенаправить его на другой URL-адрес. Этот URL-адрес, к которому я перенаправляюсь, обрабатывается другой функцией в том же файле Django views.py. Есть ли способ сделать это и сохранить исходные данные POST?

UPDATE: больше объяснений, почему я хочу это сделать. У меня есть два веб-приложения (позвоните им AppA и AppB), которые принимают данные, введенные пользователем в текстовое поле. Когда пользователь нажимает кнопку "Отправить", данные обрабатываются и отображаются подробные результаты. AppA и AppB ожидают различные типы данных. Иногда пользователь ошибочно записывает данные типа AppB в AppA. Когда это произойдет, я хочу перенаправить их в AppB и показать результаты AppB или, по крайней мере, заполнить данные, которые они ввели в AppA.

также:

  • Клиент хочет использовать два отдельных приложения, а не комбинировать их только с одним.

  • Я не могу показать код, как он принадлежит клиенту.

ОБНОВЛЕНИЕ 2: Я решил, что KISS - лучший принцип здесь. Я объединил два приложения в одном, что делает вещи более простыми и надежными; Я должен быть в состоянии убедить клиента, что это лучший способ пойти тоже. Спасибо за отличную обратную связь. Если бы я собирался поддерживать два приложения, как описано, я думаю, что сеансы будут способом сделать это - благодаря Мэтью Дж. Моррисону за это. Благодаря Dzida, поскольку его комментарии заставили меня задуматься о дизайне и упрощении.

4b9b3361

Ответ 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 %}