我们在一个项目中成功地使用了django-guardian和django-rest框架。然而,当用户拥有1000个具有所需权限集的对象时,为具有特定权限的特定用户获取对象的标准方法似乎非常缓慢。
它在IN
子句中生成一个具有1000个ID的查询。考虑到web服务器和数据库服务器之间的网络延迟,这似乎会产生后续影响:从数据库中提取1000个ID,解析它们,然后在IN
子句中将它们发送回数据库。
是否有任何记录在案的解决方法?通过使用get_objects_for_user
方法并将object_pk
列更改为整数,我能够使用内联select语句运行它:
select ... from my_table where ... and id in (select id from guardian...
与的当前声明
select id from guardian_userobjectpermissions where ...
... generate list of ids in python ...
select ... from my_table where ... and id in ([big list of ids])
我还没有尝试过的另一个变通方法是以某种方式减少监护人获取的id的范围。例如,一个用户有1000个对象,但我只对过去6个月的对象感兴趣。目前,它获取所有可能的具有用户正确权限的对象id,而不是以任何方式限制它。
我知道这是两年多前发布的,你很可能已经以某种方式解决了这个问题,但我刚刚遇到了同样的问题,并在搜索中提出了这个问题。我没有一个纯粹的ORM解决方案,但如果你愿意使用原始SQL,你可以非常有效地做到这一点。SQL看起来像这个
SELECT
obj.*
FROM guardian_userobjectpermission as op
JOIN auth_user as u ON (op.user_id = u.id)
JOIN auth_permission as p ON (op.permission_id = p.id)
JOIN django_content_type as ct ON (ct.id = op.content_type_id)
JOIN myapp_mymodel as obj ON (obj.id = op.object_pk::integer)
WHERE u.id = user_id AND p.codename = 'mymodel_perm' AND ct.model = 'mymodel' AND ct.app_label = 'myapp'
其中名为MyModel的模型位于名为myapp的应用程序中,具有名为MyModel_perm的权限,user_id是您查找对象的用户的主键。