如何在带有上下文的 Django 中重定向?

Posted

技术标签:

【中文标题】如何在带有上下文的 Django 中重定向?【英文标题】:How do I redirect in Django with context? 【发布时间】:2011-04-07 04:02:40 【问题描述】:

我有一个验证和保存表单的视图。保存表单后,我想重定向回 l​​ist_object 视图,并显示成功消息“客户 xyz 的表单已成功更新...”

HttpResponseRedirect 似乎不起作用,因为它只有一个 url 的参数,没有办法用它传递字典。

我尝试修改 object_list 的包装器,以将 dict 作为具有必要上下文的参数。我从保存表单的视图内部返回对该包装器的调用。但是,在呈现页面时,url 是“/customer_form/”而不是“/list_customers/”。我尝试修改请求对象,然后将其传递给 object_list 包装器,但这不起作用。

谢谢。

【问题讨论】:

对未来搜索者的注意:请务必阅读过去接受的答案,因为它现在已被弃用。 【参考方案1】:

request.user.message_set 在 Django 1.2 中已被弃用,自 Django 1.4 起已被删除,应使用 message framework 代替。

from django.contrib import messages

# messages.add_message(request, level, message, extra_tags='', fail_silently=False)
messages.add_message(request, messages.INFO, "Your Message")

或者,您可以使用shortcut functions 之一:

from django.contrib import messages

messages.debug(request, "Your Message")
messages.info(request, "Your Message")
messages.success(request, "Your Message")
messages.warning(request, "Your Message")
messages.error(request, "Your Message")

然后可以在模板上呈现消息:

% if messages %
    <ul class="messages">
        % for message in messages %
            <li% if message.tags % class=" message.tags "% endif %> message </li>
        % endfor %
    </ul>
% endif %

【讨论】:

我要补充一点,您可以使用 message.level_tag 来显示级别标签。成功等,这可能是有用的 tor 样式 alert- message.level_tag 例如【参考方案2】:

请注意这里建议的答案仅适用于 Django

您是否可以控制要重定向到的视图?在这种情况下,您可以在重定向之前将上下文保存在会话中。目标视图可以从会话中获取上下文(并删除它)并使用它来呈现模板。

如果您的唯一要求是显示一条消息,那么有更好的方法来做到这一点。您的第一个视图可以使用auth 为当前创建一条消息,并让第二个视图读取并删除它。像这样的:

def save_form(request, *args, **kwargs):
    # all goes well
    message = _("form for customer xyz was successfully updated...")
    request.user.message_set.create(message = message)
    return redirect('list_view')

def list_view(request, *args, **kwargs):
    # Render page

# Template for list_view:
% for message in messages %
   ... 
% endfor %

消息被保存到数据库中。这意味着即使在重定向之后您也可以访问它们。它们会在渲染模板时自动读取。您必须使用 RequestContext 才能使其正常工作。

对于 Django => 1.2 阅读涉及消息的答案

【讨论】:

另一个答案现在可能应该被接受为正确答案。这在 django 1.2 中已弃用,并在 django 1.4 中删除(如另一个答案中所述)。【参考方案3】:

扩展 Antoine 的有用答案:如果您想在视图模块而不是模板中处理消息:

from django.contrib.messages import get_messages

def my_view(request):
    # Process your form data from the POST, or whatever you need to do

    # Add the messages, as mentioned above
    messages.add_message(request, messages.INFO, form.cleaned_data['name'])

    return HttpResponseRedirect('/other_view_url/')

def other_view(request):
    storage = get_messages(request)
    name = None
    for message in storage:
        name = message
        break
    return render(request, 'general/other_view.html', 'name': name)

【讨论】:

【参考方案4】:

如果需要向重定向添加的不仅仅是一条消息,我发现以下方法可以工作:

from django.shortcuts import redirect
import urllib

def my_view(request):

    ...

    context = 'foo1': bar1, 'foo2': bar2, 'foo3': bar3
    return redirect('/redirect_link/?' + urllib.parse.urlencode(context))

另请参阅 how to pass context data with django redirect function?

【讨论】:

【参考方案5】:

在 Django 2.x + 中,您可以简单地使用 Django 自带的消息框架

views.py

from django.contrib import messages

def register(request):
    ....
    messages.success(request,"You have registered successfully, now login!")
    return redirect('login-page')

在你里面,login.html 模板确实添加了这段代码

  % if messages %
    % for message in messages %
        <div class="alert alert-success alert-dismissible fade show">
            <strong>Success!</strong> message
            <button type="button" class="close" data-dismiss="alert">&times;</button>
        </div>
    % endfor %
 % endif %

注意这个例子可以应用到任何你想显示成功消息的地方

如果您想传递错误消息,只需使用messages.error(request, "Error message")

【讨论】:

以上是关于如何在带有上下文的 Django 中重定向?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中重定向到外部 URL?

如何在 Django 中重定向到不同的 URL?

如何在传递一些上下文时在 expressjs 中重定向?

301 在 Django 中重定向 www 子域

在 Next.js 中,如何在 axios 拦截器中重定向页面?

如何在 laravel jetstream 中重定向?