我正在尝试为用户提供一个界面,以便在数据库上编写自定义查询。我需要确保他们只能查询允许他们查询的记录。为此,我决定使用 django-guardian 应用基于行的访问控制。 .
这是我的模式的样子
class BaseClass(models.Model):
somefield = models.TextField()
class Meta:
permissions = (
('view_record', 'View record'),
)
class ClassA(BaseClass):
# some other fields here
classb = models.ForeignKey(ClassB)
class ClassB(BaseClass):
# some fields here
classc = models.ForeignKey(ClassC)
class ClassC(BaseClass):
# some fields here
我希望能够使用 get_objects_for_group如下:
>>> group = Group.objects.create('some group')
>>> class_c = ClassC.objects.create('ClassC')
>>> class_b = ClassB.objects.create('ClassB', classc=class_c)
>>> class_a = ClassA.objects.create('ClassA', classb=class_b)
>>> assign_perm('view_record', group, class_c)
>>> assign_perm('view_record', group, class_b)
>>> assign_perm('view_record', group, class_a)
>>> get_objects_for_group(group, 'view_record')
这给了我一个查询集。我可以使用上面定义的 BaseClass 并针对其他相关类编写原始查询吗?
>>> qs.intersection(get_objects_for_group(group, 'view_record'), \
BaseClass.objects.raw('select * from table_a a'
'join table_b b on a.id=b.table_a_id '
'join table_c c on b.id=c.table_b_id '
'where some conditions here'))
这种方法有意义吗?有没有更好的方法来解决这个问题?
谢谢!
编辑:
解决该问题的另一种方法可能是为每个用户创建一个单独的表。我了解这可能会增加我的应用程序的复杂性,但是:
- 用户数量长期不会超过100s。不是消费者应用程序。
- 根据我们的用例,我不太可能需要跨这些表进行查询。我不会编写需要聚合表 1、表 2、表 3 中属于同一模型的任何内容的查询。
- 为每个客户维护一个单独的表格可能会有优势。
您认为这是一种可行的方法吗?
最佳答案
在研究了许多选项后,我发现我可以使用 Row Level Security 在数据库级别解决这个问题。在 PostgreSQL 上。它最终成为最简单和最优雅的。
This article帮助我将应用程序级用户与 PostgreSQL 策略联系起来。
我通过研究学到的是:
将来,当客户可能会影响彼此的查询性能时,单独的表仍然是一种选择,因为他们可以运行任意查询。
如果您计划使用原始查询或即席查询,那么尝试在 ORM 级别解决它几乎是不可能的。
关于python - Django 中多个模型的原始查询和行级访问控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47424076/