避免在Django中获取用户和权限的N + 1问题

时间:2018-11-02 20:44:44

标签: python django django-rest-framework django-guardian

我需要获取用户列表和每个用户具有的权限(监护对象权限)列表。问题是,我尝试执行此操作的所有方式都会遇到N + 1问题。是否只遍历用户列表并从集合中获取权限

for user in User.objects.all():
    data = UserSerializer(user).data
    data['permissions'] = PermissionSerializer(user.userobjectpermission_set, many=True)

或者如果我使用prefetch_related()

for user in User.objects.prefetch_related('userobjectpermission_set'):
    data = UserAndPermSerializer(user).data

最终将首先获取用户列表,然后为每个用户运行一个单独的权限查询。

我可以编写一个原始SQL语句并自己对其进行序列化,但是我宁愿使用已经拥有的序列化程序,因此希望将用户和权限作为模型实例。有什么方法可以使用ORM完成我需要的工作吗?

Django是1.11 LTS版本,我无法很快升级到2.x。

1 个答案:

答案 0 :(得分:0)

如果您要优先考虑数据库读取,而不是诸如可读性,可维护性和开发人员效率之类的事情,则可以通过两次读取来做到这一点:

  • 读取所有用户:User objects.all()
  • 读取所有权限:Permission.objects.all()

然后在应用程序级别上缝合用户权限。

这很糟,但是在数据库读取方面很有效