2010-07-25 3 views
2

Я ищу, чтобы ограничить набор запросов, который я могу получить через модель.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: Нет, это не так. См. Is it bad to use redundant relationships?.

+1

«но это плохо, если моя модельная структура становится все глубже»? Ваша модель реляционная. Не иерархическая. Ему не нужно следовать строгой иерархии. Почему вы навязываете глубокую иерархию? Поэтому реляционная база данных не предназначена для использования. Почему? –

+0

Компания, Раздел, Сотрудник и т. Д. Являются моделями. Таким образом, Секция имеет внешний ключ для Компании. Я мог бы дать друг другу модель иностранного ключа для компании, но таким образом отношение сохраняется дважды. – svenwltr

+0

«Я могу дать друг другу модель иностранного ключа компании». Почему бы вам не так? Сотрудники переходят из раздела в раздел без изменения компаний. –

ответ

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() 

Не требует разъяснений. Если нет, спросите меня.

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 

Тогда вы можете ограничить свой QuerySet так:

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

Это sloooowwww, но это все, что я могу придумать, чтобы в 2:00 AM

+0

Да, это * * медленно ;-) – svenwltr

Смежные вопросы