python - 如何将 self 对象传递给全局变量(Django View )

标签 python django performance

我正在写hellban我的基于 Django 的 Web 应用程序的功能。在各种基于类的 View 方法中,如果用户位于禁止列表中,我会触发一些功能。由于我在多个 View 中重复此比较,因此我决定将其转换为全局变量 - 在任何基于类的 View 之外 - 因此:

isbanned = HellBanList.objects.filter(condemned_id=self.request.user.id).exists()

不幸的是,我遇到了错误:名称“self”未定义,即 self 对象在基于类的 View 之外不可用。我对 request.useruser 也得到了类似的结果。

是否有任何可以用来计算此类全局变量的 self.request.user 解决方法(适用于经过身份验证和未经身份验证的用户)?我的目标是仅计算一次请求用户是否属于 hellban 列表的一部分,然后在需要的地方使用该信息。

或者由于我在这里没有预见到的问题,我应该避免这样做吗?

最佳答案

首先,全局变量不是线程安全的。想象一下同时处理两个请求。第二个请求可能会在第一个请求完成之前覆盖 isbanned,从而导致第一个请求被错误处理。

如果我是你,我会写 middleware class评估用户是否每个请求仅被禁止一次。然后将此信息存储在请求中:

class CalculateUserBannedMiddleware(object):

    def process_request(self, request):
        request.user_banned = HellBanList.objects.filter(condemned_id=request.user.id).exists()

中间件类需要在django.contrib.auth.middleware.AuthenticationMiddleware之后定义,以便能够访问request.user属性:

MIDDLEWARE_CLASSES = (
    ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'myapp.CalculateUserBannedMiddleware'

在其余代码中,您可以使用 request.user_banned 来检查当前用户是否被禁止。这样每个请求只计算一次标志。


编辑:

如果延迟计算 user_banned,您甚至可以使解决方案变得更加智能。这样,对于不需要此标志的请求,您就不会产生任何开销。

实现延迟求值的一种方法是使用具有 __bool__ 方法 (Python 3) 或 __nonzero__ 方法 (Python 2) 的对象。

Python 3 的示例实现:

class LazyUserBannedFlag(object):

    user_banned = None

    def __init__(self, request):
        self.request = request

    def __bool__(self):
        if self.user_banned is None:
            user_id = self.request.user.id
            self.user_banned = HellBanList.objects.filter(condemned_id=user_id).exists()
        return self.user_banned


class CalculateUserBannedMiddleware(object):

    def process_request(self, request):
        request.user_banned = LazyUserBannedFlag(request)

关于python - 如何将 self 对象传递给全局变量(Django View ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33585633/

相关文章:

python - 根据字典的其他值更改 python 字典的值

python - 在 python 中从 BackgroundSubtractorMOG2 获取背景模型

javascript - 在 Django 中处理没有表单的 Ajax 请求

tomcat - 通过带有 Tomcat 实例的 Apache Web 服务器服务的多个域;一个网站很慢

c++ - 检查零更有效吗?

python - 函数不改变全局变量

python - 比较 PyCharm 中的两个 Python 方法

ios - 嵌套(for-)循环的奇怪性能问题

python - 在django模板中减去两个变量

django ajax/jquery 文件上传