python - Django 中多个模型的原始查询和行级访问控制

标签 python django postgresql django-guardian

我正在尝试为用户提供一个界面,以便在数据库上编写自定义查询。我需要确保他们只能查询允许他们查询的记录。为此,我决定使用 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/

相关文章:

python - 在 python 中的 while 循环中使用多个条件

python - 如何使用我从网站上抓取的 json 填充我的 django 数据库

Python 3.4 AssertEqual() 在 Django 单元测试中使用时出现不可预测的行为

SQL - 计数有或没有子查询?

Python 和 Numba : incorrect checksum for freed object

python - 将预测结果保存到 CSV

python - 具有标量值的 Django 子查询

ruby-on-rails - RSPEC - 在加载时从文件恢复数据库

sql - 如何优化只能根据两个表区分数据的 2 表查询?

python - 如何使用多个数组优化函数?