2010-07-25 6 views
2

Je cherche de manière à limiter le jeu de requête que je peux traverser dans un modèle.Django: limitation des données du modèle

Supposons que j'ai les modèles suivants (avec dépendances):

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

Il convient de noter que mes modèles réels sont beaucoup plus profondes et ce n'est pas vraiment sur les affaires.

Avec un processeur de contexte, j'ai ajouté une instance de la société pour demander:

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

Maintenant, ma question est quelle est la meilleure façon de limiter l'accès aux modèles de l'enfant de la société à l'instance de demande de la société ?

Je pourrais faire comme task = Task.objects.get(pk=4,section__task=task), mais c'est un mauvais moyen si la structure de mon modèle devient plus profonde.

Modifier: Je pourrais donner à chaque autre modèle une clé étrangère à la société, mais est-ce une bonne pratique pour stocker des relations redondantes? Éditer 2: Non, ce n'est pas le cas. Voir Is it bad to use redundant relationships?.

+1

"mais c'est un mauvais moyen si ma structure de modèle devient plus profonde"? Votre modèle est relationnel. Pas hiérarchique. Il n'a pas besoin de suivre une hiérarchie stricte. Pourquoi imposes-tu une hiérarchie profonde? La base de données relationnelle n'est pas destinée à être utilisée pour cette raison. Pourquoi le faire? –

+0

Société, section, employé et ainsi de suite sont des modèles. Donc, Section a une clé étrangère à la Société. Je pourrais donner à chaque autre modèle une clé étrangère à la compagnie, mais de cette façon la relation est sauvée deux fois. – svenwltr

+0

"Je pourrais donner à chaque autre modèle une clé étrangère à la compagnie" Pourquoi pas vous? Les employés passent d'une section à l'autre sans changer d'entreprise. –

Répondre

1

J'ai résolu le problème de la façon suivante:

J'ai d'abord créé un 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 }) 

Puis j'ai ajouté le gestionnaire à tous les modèles où j'en ai besoin.

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

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

Et maintenant je peux facilement limiter les données du modèle dans la vue.

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

Cela devrait être explicite. Si non, alors demandez-moi.

0

Traitez votre hiérarchie sous forme de graphique. Que tous vos modèles étendent la classe 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 

Ensuite, vous pouvez limiter votre queryset comme ça:

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

Il est sloooowwww, mais il est tout ce que je peux venir au 02h00

+0

Oui c'est * lent * ;-) – svenwltr

Questions connexes