我想在Django中为我的模型实现某种行级安全性。我想根据某些要求过滤掉尽可能低的数据。
现在,我知道我可以像docs所说的那样为该模型创建指定的管理器,但是对我来说,它需要是静态的。我也知道我可以创建只需要返回查询集的方法,但是这还不够,我的意思是仅获取所有数据的可能性仍然存在,最简单的错误可能导致它们泄漏。
因此,我发现了this个帖子,但正如作者所说-与全球性国家混为一谈既不安全也不很漂亮。这篇文章已有将近10年的历史,所以我希望也许有人提出了更好的通用解决方案。
以下是一个示例,可以直观显示我的需求:
models.py:
class A(models.Model):
...
class B(models.Model):
user = models.ForeignKey(User)
a = models.ForeignKey(A)
并且我想创建全局功能,以仅当存在具有A
作为登录用户的B实例的情况下获取user
的对象。
我想出了一种解决方案,可以像这样覆盖get_queryset()
经理的A
:
managers.py
class AManager(models.Manager):
def get_queryset(self):
return super().get_queryset(b__user=**and_here_i_need_a_user**)
但是我找不到使它参数化的热力
====编辑====
另一个想法是完全不允许显式地获取A
的查询集,而只能通过B
的相关字段来获取,但是我找不到任何参考来实现该目的。有人做过类似的事情吗?
答案 0 :(得分:0)
因此,您处于正确的轨道上。这样的事情怎么样...
class AQuerySet(models.QuerySet):
def filter_by_user(self, user, *args, **kwargs):
user_filter = Q(b__user=user)
return self.filter(user_filter, *args, **kwargs)
class AManager(models.Manager):
queryset_class = AQuerySet
def filter_by_user(self, user, *args, **kwargs):
return self.get_queryset().filter_by_user(user, *args, **kwargs)
class A(models.Model):
objects = AManager()
# ...
然后您可以像这样使用它:
A.objects.filter_by_user(get_current_user(), some_filter='some_value')