Django: limiting model data
I'm searching in a way to limit the queryset which I can get through a model.
Suppose I have the following models (with dependencies):
Company
|- Section
| |- Employee
| |- Task
| `- more models...
|- Customer
| |- Contract
| |- Accounts
| `- other great models ...
`- some more models...
It should be noted that my real models are much deeper and it's n开发者_JS百科ot really about business.
With a context processor I have added a company instance to request:
def magic_view(request):
request.company # is a instance of Company model
Now my question is what is the best way to limit the access to the child models of Company to the request instance of company?
I could make it like task = Task.objects.get(pk=4,section__task=task)
, but this is a bad way if my model structure is getting deeper.
Edit: I could give each other model a foreign key to company, but is this a good practice to store relations redundant? Edit 2: No it isn't. See Is it bad to use redundant relationships?.
I solved it the following way:
First I've created a 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 } )
Than I added the manager to all models where I need it.
class Employee(models.Model):
# some fields and relationships
objects = CurrentCompanyManager("section__company")
class Accounts(models.Model):
# some fields and relationships
objects = CurrentCompanyManager("customer__company")
And now I can easily limit the model data in the view.
def magic_view(request):
Employee.objects.on(request.company).all()
It should be self-explanatory. If not, then ask me.
Treat your hierarchy as a graph. Let all your models extend the Node class:
class Node(models.Model):
parent = models.ForeignKey("Node", blah blah...)
def get_root(self):
n = self
while ((n = n.parent) != None): pass
return n
Then you can limit your queryset like that:
qset = Task.objects.filter(blah...)
result = []
for row in qset:
if row.get_root() == request.company:
result += row
It's sloooowwww, but it's all I can come up to at 2:00 AM
精彩评论