【问题标题】:Reduce number of database queries, initiated from django templates减少从 django 模板启动的数据库查询数量
【发布时间】:2014-07-31 11:54:06
【问题描述】:

我的项目有一个自定义权限模型,并且我没有使用 django 的默认权限后端。我有一个自定义 has_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 是否具有指定的权限)

【问题讨论】:

  • 这些权限多久会为用户更改/更新一次?

标签: mysql django django-templates django-queryset


【解决方案1】:

对此有多种解决方案。

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

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

一旦检查单个对象,权限就会被存储,我们不会 如果对该对象调用另一个检查,则再次点击数据库。这是 非常适合模板、视图或其他基于请求的检查(假设我们 当我们获取所有对象时,对单个对象没有数百个权限 检查对象的权限)。

【讨论】:

  • 在会话中存储权限安全吗?
猜你喜欢
  • 2020-06-02
  • 2016-07-10
  • 2011-09-24
  • 1970-01-01
  • 2014-02-07
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
  • 2017-06-01
相关资源
最近更新 更多