Django:限制模型数据

2 投票
2 回答
786 浏览
提问于 2025-04-16 01:49

我正在寻找一种方法来限制我通过模型获取的数据。

假设我有以下模型(它们之间有依赖关系):

Company
 |- Section
 |   |- Employee
 |   |- Task
 |   `- more models...
 |- Customer
 |   |- Contract
 |   |- Accounts
 |   `- other great models ...
 `- some more models...

需要注意的是,我的真实模型要复杂得多,这其实和业务没什么关系。

通过一个上下文处理器,我已经将一个公司实例添加到了请求中:

def magic_view(request):
    request.company # is a instance of Company model

现在我的问题是,如何最好地限制对公司子模型的访问,只能访问请求中的公司实例?

我可以这样做 task = Task.objects.get(pk=4,section__task=task),但如果我的模型结构更复杂,这种方法就不好了。

编辑:我可以给每个模型添加一个指向公司的外键,但这样做是否是一个好的实践呢?存储冗余关系是否合适? 编辑 2:不,这样做不好。可以参考 使用冗余关系是否不好?

2 个回答

0

把你的层级结构看作一个图。让你所有的模型都继承自Node类:

class Node(models.Model):
parent = models.ForeignKey("Node", blah blah...)
def get_root(self):
    n = self
    while ((n = n.parent) != None): pass
    return n

然后你可以这样限制你的查询结果:

qset = Task.objects.filter(blah...)
result = []
for row in qset:
    if row.get_root() == request.company:
        result += row

虽然速度很慢,但这是我凌晨2点能想到的办法。

1

我用以下方法解决了这个问题:

首先,我创建了一个叫做 CurrentCompanyManager 的管理器。

class CurrentCompanyManager(models.Manager):
    def __init__(self,field,*args,**kwargs):
        super(CurrentCompanyManager,self).__init__(*args,**kwargs)
        self.__field_name = field

    def on(self,company):
        return self.filter( **{  self.__field_name + '__id__exact':company.id } )

然后,我把这个管理器添加到所有需要它的模型里。

class Employee(models.Model):
    # some fields and relationships
    objects = CurrentCompanyManager("section__company")

class Accounts(models.Model):
    # some fields and relationships
    objects = CurrentCompanyManager("customer__company")

现在我可以很方便地在视图中限制模型的数据了。

def magic_view(request):
    Employee.objects.on(request.company).all()

这个应该很容易理解。如果不明白,可以问我。

撰写回答