【问题标题】:Decorator overwriting POST, GET and REQUEST in Django - doing it right?装饰器在 Django 中覆盖 POST、GET 和 REQUEST - 做对了吗?
【发布时间】:2012-02-01 09:15:16
【问题描述】:

在 Django 中,我创建了一个函数装饰器,在此示例中,它可以创建提供的 POST/GET 参数的小写版本,并在视图处理所有请求之前更新请求。 我为此创建了以下装饰器:

def force_lowercase(*fields):
    assert isinstance(fields, tuple), "Fields must be of type tuple."

    def wrap_func(fn):
       def wrapper(request):
           post = request.POST.copy()
           get  = request.GET.copy()
           for field in fields:
               if field in post:
                   post[field] = post[field].lower()
               if field in get:
                   get[field]  = get[field].lower()

           request._post = post   
           request._get = get
           request._request = MergeDict(post,get)

           return fn(request)
       return wrapper
   return wrap_func

在我看来,我会有类似的东西:

@force_lowercase(email,zipcode)
def index(request)
    #blabla

这是正确的方法吗?我有点担心我以这种方式破解 Django 的 WSGIRequest 对象,其他 Django 功能可能看不到更新的 GET/POST/REQUEST 对象。

【问题讨论】:

  • 你可以考虑开发一个中间件来拦截请求发布并获取数据,修改它们并将它们传递给底层函数。
  • @Jingo:我想过,但我并不总是想修改数据。此外,我希望能够指定视图中每个函数应针对哪些字段。 .....让我想起了那个模因家伙:“我并不总是修改数据,但当我这样做时,我会以最佳精度获得我的目标”:P

标签: python django decorator


【解决方案1】:

如果您使用的是表单,则可以在表单本身中使用小写。

虽然实施在 IMO 有效,但我有一个问题,即对于每次调用,您最终都会复制 get/post 字典、搜索它们、转换字段并将结果附加为您需要知道的 request._request即将能够使用它。我觉得有点矫枉过正...

我会用一个在视图中调用的简单方法来更改它(根据您的情况,您可以用小写的值覆盖原始值或创建新元素)。

另一种解决方案是通过 javascript 在 HTML 页面中执行此操作。您可以(硬)编码模板,创建自定义小部件,或使用小部件中指定的属性加上 jquery 调用...

【讨论】:

  • 感谢您的回答。我正在构建某种没有自己的表单的后端系统,并且我有许多仅使用小写输入的视图。在可读性和可重用性方面,装饰器似乎是我的最佳选择。我在我的应用程序的更多模块中使用装饰器。
  • 我对装饰器有两个担忧; 1. 处理开销(如上)和 2. 您以后可能会遇到它的风险。我对此有一个经验法则:如果有很多地方可以使用它,那么就编写一个装饰器。否则,请尝试在视图中显式执行。
  • 我在很多地方都使用它...所以经验法则在这里适用 :-) 但是,我只是注意到在这个例子中我经常覆盖 POST/GET/REQUEST,将修复缩进就像在我的 IDE 中一样。
  • 好的:)。然后,您可以覆盖 request 中的原始字典或创建新字段(在字典中或在原始字典中),而不是复制整个 post/get 字典。我在想,如果您有一个包含很多字段或一些大型文本区域的表单,则装饰器可能需要比实际逻辑更长的时间。您还可以将其拆分为两个装饰器(一个 get 和一个 post)并根据需要使用它们。
  • 问题是你不能直接覆盖键,它会抛出一个 ImmutableDict 错误:-)
猜你喜欢
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-19
  • 2016-04-28
  • 2023-04-06
  • 2013-10-17
  • 2019-10-02
  • 1970-01-01
相关资源
最近更新 更多