【问题标题】:Make extra parameters passed in URL as optional使在 URL 中传递的额外参数作为可选参数
【发布时间】:2019-08-08 07:44:10
【问题描述】:

我有这个网址path('user/delete/<int:pk>/', views.UserDeleteView.as_view(), name='delete_user'),

通过传递DeleteView 要访问的用户的pk 来删除选定的用户。但是,我想通过使用带有复选框的表单来删除多个用户。为此,我使用了单独的视图。

我的问题是,有什么方法可以将 <int:pk> 作为可选参数,这样我就可以对 POST 和 GET 请求使用相同的视图。以防万一我想对同一个 URL 使用 POST 方法。这可以做到吗?有人说它可以在 Ruby on Rails 中可选。在 Django 中有没有办法做到这一点?

【问题讨论】:

  • 我只允许超级用户。我实际上是在尝试创建 Django 提供的管理界面的副本。
  • 这不相关。 HTTP 标准规定 GET 用于检索信息,而不是更改信息:“GET 方法意味着检索任何信息(以实体的形式)由 Request-URI 标识。如果 Request-URI 指的是数据生成过程,则生成的数据应作为响应中的实体返回,而不是过程的源文本,除非该文本碰巧成为进程的输出。" (src: w3.org/Protocols/rfc2616/rfc2616-sec9.html)
  • 您能告诉我是否可以将<int:pk> 参数设为可选参数吗?有什么办法吗? @WillemVanOnsem

标签: django django-templates django-views django-urls


【解决方案1】:

您可以定义两条路径,一条带有主键,另一条没有主键:

path('user/delete/', views.UserDeleteView.as_view(), name='delete_user'),
path('user/delete/<int:pk>/', views.UserDeleteView.as_view(), name='delete_user_id'),

因此,我们在这里有两个视图:'delete_user' 不接受 pk'delete_user_id' 接受主键。两者都指向同一个UserDeleteView

您可以使用kwargs= 参数为缺少的参数注入一个值:

path('user/delete/', views.UserDeleteView.as_view(), name='delete_user', kwargs={'pk': None}),
path('user/delete/<int:pk>/', views.UserDeleteView.as_view(), name='delete_user_id'),

话虽如此,使用 GET 请求应该没有副作用。这就是HTTP protocol [wiki] 的设计方式:

GET 方法请求指定资源的表示。使用 GET 的请求应只检索数据,不应有其他影响。 (其他一些 HTTP 方法也是如此。)W3C 已经发布了关于这种区别的指导原则,称“Web 应用程序设计应遵循上述原则,但也应遵循相关限制。”。

W3 组织也有guidelines when to use GET or POST:

在以下情况下使用 GET:

  • 交互更像是一个问题(即,它是一种安全操作,例如查询、读取操作或查找)。

在以下情况下使用 POST:

  • 交互更像是一个订单,或者
  • 交互以用户感知的方式更改资源的状态(例如,订阅服务),或
  • 用户应对交互结果负责。

如果您想删除项目,通常会发出 DELETE 或 POST 请求。例如,Django 将使用 CSRF 令牌保护此类请求,以防止 cross-site request forgery [wiki]

因此,我强烈建议您只允许这些视图的 POST/DELETE 请求,当然还要额外检查用户是否有权进行更改。

【讨论】:

  • 如何使用删除视图删除一个对象的多个实例?
  • @Deshwal:你是如何实现UserDeleteView的?
  • 类 UserDeleteView(DeleteView): success_url= reverse_lazy('admin:user_list') model = User
  • @Deshwal:Django 的内置删除视图没有“批量”删除功能,而且默认实现只接受 URL 参数。
  • 它使用 get 方法删除单个对象。但是如何通过 Post 方法一次删除多个对象呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 2018-01-15
  • 1970-01-01
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多