2010-06-25 4 views
0

J'ai un système avec plusieurs sites dedans. Chaque objet Utilisateur du système reçoit un objet Profil qui détermine les sites avec lesquels ils peuvent interagir. Le système a également un modèle d'article qui peut appartenir à plusieurs sites. Ainsi, quand un utilisateur charge la page d'admin d'article, je veux seulement qu'ils voient des articles qui sont assignés aux emplacements qu'ils ont l'accès pour voir. Donc, je substituez la méthode queryset la classe Administrateur de l'article avec quelque chose comme ceci:Override de la méthode du Queryset de Django Admin; Requête mal exécutée

qs = model.objects.filter(sites__id__in=[x.id for x in user.get_profile().group_profile.allowed_sites.all()]).distinct() 

Prendre l'utilisateur, obtenir les sites auxquels ils ont accès, et en tirant les articles dont l'affectation est le site dans cette liste. Le problème est, cette requête devient un vrai chien une fois que vous obtenez quelques centaines de milliers d'articles et est exacerbé par le modèle lui-même étant grand, ce qui signifie que Django tire beaucoup de données et exécute un DISTINCT sur une grande liste de colonnes.

Je cherche des moyens de l'améliorer, mais la méthode du jeu de queues ne semble pas me donner beaucoup de chance. Au départ, j'ai essayé d'utiliser la fonction QuerySet only() pour extraire uniquement les colonnes dont j'ai besoin pour dessiner la liste des modifications, mais j'ai trouvé que cela provoquait des signaux post-enregistrement pour que le modèle ne se déclenche pas. Je ne peux pas me débarrasser du distinct, car si je le fais, j'obtiendrai plusieurs résultats par site: si l'utilisateur peut voir le site A et le site B, et qu'un article appartient aux deux sites, la requête retournera l'article. deux fois.

Répondre

1

Si vous avez une relation ManyToMany, vous ne pouvez pas vous débarrasser du distinct() car plusieurs jointures doivent être effectuées pour chaque instance. Quelque chose que vous pouvez faire au sujet de votre requête (bien que je ne pense pas que ce sera une grande amélioration des performances), vous ne devez pas faire le « __in » avec les IDs interrogeant:

qs = model.objects.filter(\ 
     sites__in=user.get_profile().group_profile.allowed_sites.all()).distinct() 
+0

Comme vous l'avez dit, Cela n'affecte pas vraiment la vitesse. Le site allowed_sites est une liste courte d'une petite table (15 max). C'est la distinction qui le tue vraiment, ou du moins de cette façon que Django semble m'obliger à tirer chaque colonne du modèle, rendant la comparaison distincte() brutale. – KRH

+0

cela peut-il être ce que vous cherchez? http://docs.djangoproject.com/fr/1.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset – FallenAngel

Questions connexes