在Django中编写线程安全中间件的好方法

时间:2018-09-27 09:32:31

标签: python django django-orm django-middleware

我要对大型Django应用程序中的几乎所有模型和所有查询应用所需的过滤。 实际上,我正在寻找一种实现“查询集驱动”中间件(而不是标准的“请求驱动中间件”)的正确方法。 但无需操纵任何数据库驱动程序(不进行修补,包装等)。

想法是对QuerySet和Manager使用一个通用的混合,以查看此方法始终可用:

AnyModel.objects.filter_by_organization()

不需要在那里传递参数。

及更高版本:

AnyModel.org_objects做着filter_by_organization()自己的自我

我主要关心的是线程安全性。 您可以在下面查看我的方法吗? this_thread = threading.local()

... standard django middleware:
class OrganizationMiddleware(object):
    def process_request(self, request):
        this_thread.request = request

    def process_response(self, request, response):
        if hasattr(this_thread, 'request'):
            del this_thread.request   # doubtful
        return response

    def process_exception(self, request, exception):
        if hasattr(this_thread, 'request'):
            del this_thread.request   # doubtful
    ...

... mixin/manager:
class OrganizationQuerySet(models.QuerySet):
   def _get_current_request(self):
       return getattr(this_thread, "request", None)

   def filter_by_organization(self):
       request = self._get_current_request()
       org_id = getattr(request.user, 'organization_id', None)
       return self.filter(...filtering by org_id + extra logic...)
       # keeping this in one place has additional benefits

... in models: 
org_objects = OrganizationQuerySet.as_manager()

... then using above without a need to pass request

0 个答案:

没有答案