开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜