在Django中传递消息并重定向

7

我想在检查用户的user_settings是否存在后运行重定向(如果不存在,则将用户带到输入和保存它们的表单)。

我想将用户重定向到适当的表单,并向他们提供消息,让他们知道他们需要“保存设置”,以便他们知道为什么被重定向。

该函数如下:

def trip_email(request):
    try:
        user_settings = Settings.objects.get(user_id=request.user.id)
    except Exception as e:
        messages.error(request, 'Please save your settings before you print mileage!')
        return redirect('user_settings')

这个函数检查用户设置并适当地重定向我,但消息从未出现在模板的顶部。
你可能会首先想:“Django中的消息设置正确吗?”
我有其他功能,在那里我使用消息而不是重定向,消息显示为预期的模板,没有问题。消息已经适当地集成到我的模板中,并且可以正常工作。
只有当我使用“redirect”时,我才看不到我发送的消息。
如果我像下面这样使用“render”,我就会看到消息(但是,URL不会更改 - 我希望这种情况发生)。
def trip_email(request):
    try:
        user_settings = Settings.objects.get(user_id=request.user.id)
    except Exception as e:
        messages.error(request, 'Please save your settings before you print mileage!')
        form = UserSettingsForm(request.POST or None)
        return render(request, 'user/settings.html', {'form': form})

我有一些其他地方需要使用重定向redirect,因为这样做在功能上是有意义的 - 但我也希望将消息传递给这些重定向页面。

user_settings函数如下:

def user_settings(request):
    try:
        user_settings = Settings.objects.get(user_id=request.user.id)
        form = UserSettingsForm(request.POST or None, instance=user_settings)
    except Settings.DoesNotExist:
        form = UserSettingsForm(request.POST or None)
    if request.method == 'POST':
        settings = form.save(commit=False)
        settings.user = request.user
        settings.save()
        messages.warning(request, 'Your settings have been saved!')

    return render(request, 'user/settings.html', {'form': form})

我在文档中找不到任何关于不能使用重定向发送消息的内容,但是我无法弄清楚如何显示它们。

编辑: 以下是我在模板中呈现消息的方法:

{% for message in messages %}
  <div class="alert {{ message.tags }} alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
    {{ message }}
  </div>
{% endfor %}

我不确定这是否有影响,但似乎从某个地方调用了两次“GET”。

is calling get twice like this normal?

这两个URL的URL部分看起来像是这样的:

# ex: /trips/email
url(r'^trips/email/$', views.trip_email, name='trip_email'),
# ex: /user/settings
url(r'^user/settings/$', views.user_settings, name='user_settings'),

2
尝试一件事,只需在该函数中保留消息并重定向,删除try catch并命中该视图的URL,然后检查是否出现消息。 - Exprator
1
当我在 trip_email 中去掉 try-catch 并只保留消息和重定向时,我看不到消息。 - Hanny
有没有什么方法可以排除缓存的影响?例如在URL中添加“?random=12345”这样的参数? - user1600649
1
好的,非常好。这确实在Django中没有注册。奇怪的是,我正在做完全相同的事情,只是使用类视图(在form_valid中)。因此,我试图弄清楚那个特殊的东西是什么。好的,试试这个:response = redirect('viewname') messages.error(request, 'wrong!') return response(三行) - user1600649
嘿@hanny,删除返回并仅保留重定向,检查一次。 - Exprator
显示剩余17条评论
2个回答

2

我认为最好的方法是使用会话。

从django.contrib导入messages << 如果你选择使用django消息,则可选。

处理您的表单

def handle_form(request):
    ...
    request.session['form_message'] = "success or fail message here"

    redirect('/destination/', {})

def page_to_render_errors():
    ...
    message = None
    if( 'form_message' in request.session ):
        message = request.session['form_message']
        del request.session['form_message']
        messages.success(request, message ) #<< rememeber messages.success() along with messages.info() etc... are method calls if you choose to pass it through django's messaging

    return render(request,'template_name.html', {'message_disp':message })

1
您无法查看错误消息,因为它未被呈现,因此消息无处可去。做这样的事情的最佳方法是呈现一个中间页面,显示错误消息,并在超时后重定向,类似于支付网关将您重定向到银行的方式。
您可以这样做:
def trip_email(request):
    try:
        user_settings = Settings.objects.get(user_id=request.user.id)
    except Exception as e:
        return render(request, 'no_setting_error.html', {'form': form})

no_setting_error HTML页面上,插入JavaScript以在超时后自动重定向,例如:
<script>
    function redirect(){
       window.location.href = "/user_settings";
    }

    setTimeout(redirect, 3000);
</script>

这将在错误页面停留 3 秒后自动将您重定向到 user_settings 页面。

虽然这可能是一个解决方法,但消息被存储在会话中并且可以被传递。只要会话仍然存在,就会显示消息。正如我在基于类的视图中所做的那样,它们会重定向到 success_url。请参见我的答案中的 ModelFeedbackMixin 这里。最上方的 form_valid 函数将执行 return HttpResponseRedirect(self.get_success_url()) - user1600649

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接