减少从django模板启动的数据库查询数量

时间:2014-06-10 16:03:22

标签: mysql django django-templates django-queryset

我的项目有自定义权限模型,我没有使用django的默认权限后端。我有一个自定义的has_permission模板标记来检查用户是否具有指定的权限。

问题是每次都有相同检查的大量查询,我正在寻找一种方法来减少我的Permission查询。我在模板中做的是:

    {% if user|has_permission:'jpermission.can_edit_jpermission' or 
          user|has_permission:'jgroup.can_edit_jgroup' or 
          user|has_permission:'role.can_edit_role' %}

和has_permission模板标记的代码如下:

rep = perm_name.split('.') # rep is for e.g. "jpermission.can_edit_jpermission"
ctn_type = rep[0]
codename = rep[1]

pr = JPermission.objects.filter(model_name=ctn_type, codename=codename)
if pr.exists():
    if user.has_perm(pr[0]):
        return True

具体说来,问题是每次我检查完全相同的if语句时,都会进行大量的查询(从我正在做的事情来看,很明显会有)。

还有其他方法我可以去吗?比如查询所有权限一次,缓存它们,并执行类似如何处理prefetch_related以禁止进一步的数据库查询(带循环和...的python过滤)?

P.S:has_perm也被覆盖并检查用户rolegrouppermissions是否具有指定的权限)

1 个答案:

答案 0 :(得分:1)

有多种解决方案。

  • 将权限移动到用户模型作为模型的方法,并使用cached_property装饰器,以便连续调用方法不会再次命中数据库。
  • 在用户登录时将权限状态存储在会话中,稍后使用会话数据来检查权限。

看起来你正在使用django-guardian,它已经是caching the permissions

  

检查单个对象后,将存储权限,但我们不会   如果为此对象调用另一个检查,则再次命中数据库。这是   非常适合模板,视图或其他基于请求的检查(假设我们   在我们获取所有对象时,对单个对象没有数百个权限   已检查对象的权限。)