【问题标题】:What's a good way to handle url parameters types?处理 url 参数类型的好方法是什么?
【发布时间】:2014-09-08 12:58:27
【问题描述】:

想象一个具有以下url.py 的应用程序:

urlpatterns = patterns('',
    url(r'^$', views.index),
    url(r'^double/(?P<number>\d+)/$', views.double),
)

还有这个views.py

def double(request, number=42):
    return HttpResponse(2*number)

显然,我希望 number 始终被视为一个整数。在查询/double/5/ 时,我总是希望得到10,而不是55

有什么好的方法来处理在 Django url 中输入的参数吗?

【问题讨论】:

    标签: python django django-urls


    【解决方案1】:

    This thread 表示自动转换不是一个好的解决方案:

    请注意,自动转换也不是一个好计划。为了 例如,我博客的下一个版本将 2008/2/25/ 之类的 URL 转换为 2008/02/25/ 因为我想要一个规范的形式。所以我需要知道是否 \d{1,2} 匹配两个数字之一,即使第一个是 0。 自动转换为整数将删除该功能(它是 不难想到这样的其他情况)。所以你需要 可配置。

    也提出了一个基于装饰器的解决方案,但我不是很服气,听起来有点繁琐:

    您的问题的一个解决方案可能是编写一个装饰器 类型列表(加上“不关心”的 None 之类的东西)和 自动将参数 N 转换为第 N 个元素中的类型 调用函数之前的列表

    【讨论】:

      【解决方案2】:

      这是一个基于装饰器的解决方案:

      def param_type(**type_spec):
          def deco(f):
              def view(request, **kwargs):
                  for k, type_ in type_spec.items():
                      kwargs[k] = type_(kwargs[k])
                  return f(request, **kwargs)
              return view
          return deco
      
      @param_type(number=int)
      def double(request, number=42):
          return HttpResponse(2*number)
      

      【讨论】:

      • 谢谢!但这被认为是一种好习惯吗?还是应该将 url 参数输入视为要避免的事情?
      • @Anto,我个人不使用自动类型转换装饰器。我只是在视图代码中手动转换。
      【解决方案3】:

      安托,

      我认为您的问题与网址有关。 (?P&lt;number&gt;\d+) 是一个正则表达式,声明 \d 只允许数字它与 [0-9] 相同。 + 符号告诉它需要 1 个或多个数字。因此,如果您尝试插入 double/notanumber/ 之类的内容,它将无法正常工作。

      了解这一点后,您可以放心地假设:

      1:数字总是有值的

      2: number 永远是一个整数(即使 django 将它作为 unicode 返回)

      我对你的函数做了一个小改动:

      def double(request, number): # removed the =42 because number can never be empty
        return HttpResponse(2 * int(number)) # Converted your number to an integer
      

      【讨论】:

      • 我明白这一点,但我的问题实际上是关于:处理 number arg 类型的 最佳实践 知道 1/ 它总是由url 解析器作为一个字符串和 2/ 我总是需要一个整数。这确实是一个关于最佳实践的问题,如果我不够清楚,抱歉;)
      • 我想如果你知道它总是number 并且总是希望它是integer 你可以简单地使用int()
      猜你喜欢
      • 1970-01-01
      • 2019-03-25
      • 2020-06-02
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多