2009-12-23 7 views
6

Je le code suivant:Rédaction d'un gestionnaire pour filtrer ensemble de résultats de requête

class GroupDepartmentManager(models.Manager): 
    def get_query_set(self): 
    return super(GroupDepartmentManager, self).get_query_set().filter(group='1') 

class Department(models.Model): 
name = models.CharField(max_length=128) 
group = models.ForeignKey(Group) 
def __str__(self): 
    return self.name 
objects = GroupDepartmentManager() 

... et il fonctionne très bien. La seule chose est que je dois remplacer group='1' avec group=(the group specified by group = models.ForeignKey(Group)). Je passe un certain temps à essayer de déterminer si cette clé étrangère doit être transmise dans la classe, ou dans la fonction get_query_set, ou quoi. Je sais que vous pouvez accomplir ceci avec group.department_set.filter(group=desired group), mais j'écris ce modèle pour le site d'admin, ainsi j'ai besoin d'employer une variable et pas une constante après le signe =.

+2

J'ai de la difficulté à comprendre ce que vous essayez d'accomplir. Voulez-vous que department_instance.objects.all() renvoie uniquement les départements appartenant au même groupe que department_instance? - Maciej Pasternacki il ya 0 secondes –

+0

Oui John votre cas n'est pas clair. Qu'est-ce qui a défini quel groupe doit être sélectionné par Department.objects.all(), par exemple? – kibitzer

+0

Ok, donc il y a une liste de groupes. Chaque groupe a quelques départements. J'ai aussi quelques employés. Chaque employé appartient à exactement un groupe et un département. Lorsque je modifie un employé, la liste déroulante des services affiche tous les départements de la base de données, et pas seulement les départements du groupe de l'employé. Donc, je veux seulement montrer les départements dans le groupe de l'employé. J'ai pensé que je pouvais le faire en limitant les résultats du département à ceux d'un groupe particulier. Peut-être que je suis vraiment confus. Mais c'est ce que j'essaie d'accomplir. – John

Répondre

4

J'ai le pressentiment que le remplacement par défaut Manager sur objects de cette manière peut-être pas une bonne idée, surtout si vous prévoyez d'utiliser le site admin ... Même si elle vous aide avec vos employés, il a gagné » t vous aider du tout lors de la manipulation des départements. Que diriez-vous d'une deuxième propriété offrant une vue restreinte sur les départements à côté de l'habituel objects? Ou déplacez la norme Manager de objects vers _objects et renommez from_same_group en objects si vous préférez vraiment votre approche originale pour votre application.

class Department(models.Model): 
    name = models.CharField(max_length=128) 
    group = models.ForeignKey(Group) 
    def __str__(self): 
     return self.name 
    objects = models.Manager() 

    @property 
    def from_same_group(self): 
     return Department.objects.filter(group__exact=self.group) 

Aussi, je comprends que vous savez comment configurer le site d'administration pour tirer profit du Manager drôle; si ce n'est pas le cas (ou si j'ai mal compris votre question), laissez un commentaire, j'essaierai de faire un suivi très bientôt.


EDIT: OK, pour le rendre plus clair: si vous tenez absolument à remplacer objects, vous auriez probablement envie de faire ceci:

class Department(models.Model): 
    name = models.CharField(max_length=128) 
    group = models.ForeignKey(Group) 
    def __str__(self): 
     return self.name 

    _objects = models.Manager() 

    @property 
    def objects(self): 
     # note the _objects in the next line 
     return Department._objects.filter(group__exact=self.group) 
+0

Je crains de ne pas avoir la moindre idée. J'ai changé de_same_publisher à from_same_group. Mais ne voudrais-je pas dire objects = from_same_publisher()? – John

+0

Ouch, le bit d'éditeur vient d'où j'ai utilisé un code similaire ... Quoi qu'il en soit, je vais modifier pour rendre les choses plus claires. –

+0

Merci, mais j'ai ajouté ceci à la classe Département, et la boîte de sélection montre toujours tous les objets du département. Je pense que je dois encore configurer la page d'administration pour, comme vous l'avez indiqué, profiter de cette configuration. Je suis confus parce que je pensais que toutes les affaires du gestionnaire ont eu lieu à l'intérieur de models.py, sans modifications dans admin.py. – John

2

Vous pourriez vouloir reconsidérer la relation entre les groupes et les départements si vous trouvez que tenter de créer un gestionnaire personnalisé est trop complexe. Les gestionnaires excellent dans la simplification des requêtes courantes, mais se trompent dans l'affichage des relations complexes entre les modèles et les instances de modèles.

Cependant, je pense que cet article à propos de filtering model objects with a custom manager vous pointera dans la bonne direction. L'auteur propose une technique pour effectuer un appel de fonction qui renvoie une classe de gestionnaire personnalisée dont les paramètres de filtre que vous spécifiez sont enregistrés dans la classe afin qu'ils ne soient pas transmis à l'instance. Fais le!

+0

Super lien, merci. C'est certainement un hack, mais je vais essayer cela et rendre compte. – John

+0

Pas moyen! C'est trop dynamique pour être un hack! Je pense vraiment que c'est assez intelligent. – jathanism

+0

Assez juste! J'ai implémenté ceci avec "objects = get_filter_manager (groupe = groupe)" dans la classe Department et j'ai reçu le même bloc d'achoppement que j'ai toujours reçu auparavant: "L'objet '' str 'n'a pas d'attribut' creation_counter '". Je n'arrive pas à mettre le code en retrait, ou je le posterais tout ici. – John

Questions connexes