【问题标题】:URLs and side effects (Django)URL 和副作用 (Django)
【发布时间】:2010-06-27 09:36:21
【问题描述】:

我想知道是否可以(特别是在 Django 中)拥有一个仅用于具有副作用的操作的 URL,该 URL 仅用于通过 POST 访问,并且用户基本上不可见。比方说,为了具体化,我的网站上有一个小消息系统,用户应该能够从他们的收件箱中执行以下操作:

  • 删除消息
  • 将邮件标记为已读
  • 将邮件报告为垃圾邮件

所有这些都会导致页面刷新,但会返回到同一页面。我想知道如何围绕这个设计我的 URL 和视图。我看到(至少)两个选项,我不知道哪个更惯用。

选项 1)

每个操作都有一个单独的 URL 和视图。因此,/inbox/delete-message/ 映射到 views.delete_message,依此类推。在每个视图结束时,它会重定向回 /inbox/。

我喜欢用这个选项清楚地分开事物的方式。如果用户以某种方式发现自己向 /inbox/delete-message/ 发送了一个 GET 请求,那会出现一种奇怪的情况(我会抛出一个错误页面吗?默默地重定向它们?)。

选项 2)

对每个操作使用相同的 URL 和视图,并具有标识操作的 POST 参数。所以我会有一个相当长的收件箱视图,其中会有一堆 if 语句测试 request.POST['action'] == 'delete' 还是 request.POST['delete'] == 'true' 或其他什么.

我觉得这个选项不太干净,但我也觉得它更常见。

Djangonauts 更喜欢哪个?还是有比上述任何一个更好的选择?

【问题讨论】:

    标签: python django url post django-views


    【解决方案1】:

    修改后的选项#1 是最好的方法。考虑一下:假设我们不是在谈论 Web 应用程序,而只是在设计一个收件箱类。您更喜欢哪一种,多种方法(delete_message()mark_as_spam() 等),还是一种大方法(do_stuff(action))?当然你会使用单独的方法。

    每个操作都有一个单独的 URL,每个操作都有一个单独的视图,这是更可取的。如果您不喜欢最后的重定向,请不要使用它。相反,有一个返回 HttpResponse 的 render_inbox(request) 方法,并在每个视图的末尾调用该方法。当然,在 POST 之后进行重定向是防止双重操作的好方法,并且始终为用户提供一致的 URL。

    使用 Ajax 来隐藏动作可能更好,但这涉及更多。

    【讨论】:

      【解决方案2】:

      我认为这两个选项都没有问题,但从性能的角度来看,#2 可能更好。发布操作后,您可以在没有重定向的情况下呈现收件箱,从而减少 HTTP 流量。

      【讨论】:

        【解决方案3】:

        如果您正在编写一个 web 2.0 消息传递应用程序,那么您将使用 AJAX 调用并且根本不会加载新页面。该过程将像这样进行:

        1. 用户单击 [删除] 以获取消息。此按钮绑定了一个 JavaScript 操作。此操作执行以下操作:

          我。更改 UI 以指示正在发生的事情(使消息变灰或竖起沙漏)。

          二。向 /messages/inbox/1234/delete 发送请求。 (其中 1234 是指示哪条消息的标识符)

          三。当来自服务器的响应返回时,它应该指示成功或失败。在当前 UI 中反映此状态。例如,成功时,刷新收件箱视图(或仅删除已删除的项目)。

        在服务器端,现在您可以为每个所需的操作(即 /delete、/flag 等)创建一个 URL 处理程序。

        如果想使用更加 RESTful 的方法,您可以使用 HTTP 操作本身来指示要执行的操作。因此,不是在您的 URL 中包含 delete,而是在操作中。因此,不要使用 GET 或 POST,而是使用 DELETE /messages/inbox/1234。要设置已读标志,请使用SET /messages/inbox/1234?read=true

        我不知道在 Django 中实现后一个建议有多简单,但总的来说,利用协议(在本例中为 HTTP)是一个好主意,而不是通过将您的操作编码到 URL 中来解决它或参数。

        【讨论】:

          【解决方案4】:

          我同意 #2 是更好的方法。

          但请注意使用不同的方法重载提交 <input /> - 如果用户通过键盘输入使用它并按 Enter 键,它不一定会提交您期望的 <input />。要么禁用输入时自动提交,要么编写代码,以便如果提交可以做的事情不止一件事,还有另一个字段设置操作应该是什么(例如,“删除”复选框,在一个请求。POST)

          如果您选择 #1,我会说 GET 到仅 POST 视图应该遇到 405(不支持方法) - 或者,如果失败,则为 404。

          【讨论】:

            猜你喜欢
            • 2012-02-28
            • 2021-01-04
            • 2023-04-06
            • 2015-09-15
            • 2018-02-02
            • 2012-10-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多