2

我们在一个项目中成功地使用了 django-guardian 和 django-rest-framework。但是,当用户拥有 1000 个具有所需权限集的对象时,为具有某些权限的特定用户获取对象的标准方法似乎非常慢。

IN它在一个子句中生成一个包含 1000 个 ID 的查询。当考虑到 Web 服务器和数据库服务器之间的网络延迟时,这似乎会产生后续影响:从数据库中提取 1000 个 id,解析它们,然后在IN子句中将它们发送回数据库。

是否有任何记录在案的解决方法?使用该get_objects_for_user方法并将object_pk列更改为整数,我能够使用内联选择语句运行它:

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,而不是以任何方式限制它。

4

1 回答 1

0

I know this was posted over two years ago and you have most likely resolved this problem one way or another, but I have just hit the same problem and came up with this question in my search. I do not have a pure ORM solution, but if you are willing to use raw SQL, you can do this pretty efficiently. The SQL looks like this

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'

where a model named MyModel lives in an app called myapp, has a permission called mymodel_perm and user_id is the primary key of the user you are looking up objects for.

于 2018-09-07T21:15:34.310 回答