【问题标题】:Change url after a form submission without using a redirect在不使用重定向的情况下提交表单后更改 url
【发布时间】:2019-09-17 08:20:26
【问题描述】:

在提交注册表后,我希望用户转到感谢/确认页面。

注册表在/register/,确认页面在/register/confirm/

我知道我可以这样做:

if register_form.is_valid():
#save data etc.


#SCENARIO 1
#go to the confirmation view
return register_confirm(request)

这会在浏览器中显示确认页面,但实际 URL 不会从 /register/ 更改为 /register/confirm/。

#SCENARIO 2
#redirect to confirmation view
return redirect('register_confirm')

这会在浏览器中显示确认页面,并且实际 URL 确实从 /register/ 更改为 /register/confirm/(在@Borut 评论后编辑)

#SCENARIO 3
#redirect to URL
return redirect('confirm/')

这会在浏览器中显示确认页面,并且实际 URL 确实从 /register/ 更改为 /register/confirm/

因此,上面第 2 和第 3 中的场景在向用户显示确认页面和在浏览器中更改 URL 方面符合我的要求。 (对我来说,浏览器中的 URL 发生变化很重要,但并非最不重要的原因是因为我希望我的分析记录对确认页面的点击)。

但是,我真的不认为在这种情况下使用“重定向”是正确的。我只是想将用户移动到确认页面(以避免在他们按下刷新时意外重新提交表单)。据我了解,重定向会给出 301 或 302 状态码,例如,暗示页面已被临时或永久移动。

在简单地将用户移动到新页面的场景中(即链接而无需他们实际点击链接),注册和确认页面的状态码应该是 200。我不想搜索引擎认为我正在重定向 /register/ URL,例如使用 301 或 302 状态代码。

请有人解释如何将用户移动到新页面,在浏览器窗口中显示不同的 URL,但不使用重定向,或者至少不提供 30x 状态代码。

谢谢!

【问题讨论】:

  • 那么,搜索引擎应该在您的网站上注册并获得确认页面吗?好吧,它不会。如果你做了重定向并且 URL 没有改变,那么你做错了什么。原则上,当用户注册时,POST请求是在/register/发出的,如果你在post成功后重定向用户,重定向是用302状态码完成的,/register/confirm/是用GET请求和200状态码呈现的。
  • 所以如果重定向是使用 302 状态码完成的,当用户提交表单时,这不是告诉搜索引擎 /register/ 已暂时移至 /register/confirm/ 吗?这是我不想要的。你是对的 - 我知道搜索引擎不会在我的网站上注册,但是当用户提交表单时,/register/ 页面是否没有分配 302 代码?
  • 当用户浏览到 /register/ 时,带有表单的页面将被加载 200 状态(GET 方法)。这是搜索引擎将看到的。当用户注册并在成功 POST 后被重定向时,服务器将指示浏览器以 302 状态码和重定向 url 重定向到提供的 url。 Here 是代码的样子。

标签: django


【解决方案1】:

如果您根本不想使用redirect,您可以从确认 URL 调用注册视图并呈现不同的模板。

您没有透露太多代码,所以这里是一个通用示例:

urls.py

from . import views

path("register/", views.your_register_view)
path("register/confirm/", views.your_register_view)

register_template.html

<form action="register/confirm/" action="post">
  <input type="submit" value="register">
</form>

views.py

def your_register_view(request):
    if request.method == "POST":
        #validate form data here
        return render(request, "confirm_template.html")
    else:
        return render(request, "register_template.html")

基本上你从两个不同的 url 调用同一个视图并根据请求类型(POST 或 GET)呈现模板。

【讨论】:

  • 感谢您的建议,这是一个很好的建议,但我不想从 DRY 的角度将 URL 硬编码到表单操作中,而且我想处理所有在用户被发送到确认页面之前 /register/ 页面上的表单验证错误,因此在这种情况下将表单操作设置为直接进入确认页面将不起作用。
  • 给你的路径一个名称参数,并将 {% url 'confirm_page_name %} 添加到表单的操作属性中。您不会在代码中重复自己,这样 url 就不会被硬编码。此外,在调用另一个视图之前,您可以做的唯一验证是在客户端使用 javascript(当然,除非您使用 ajax 来调用另一个 Django 视图。)
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2013-08-11
  • 2023-04-06
  • 2019-02-13
  • 2017-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多