Django:限制模型数据
我正在寻找一种方法来限制我通过模型获取的数据。
假设我有以下模型(它们之间有依赖关系):
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()
这个应该很容易理解。如果不明白,可以问我。