Supposons que j'ai un modèle Book contenant une clé étrangère vers un modèle Publisher.
Comment afficher dans l'admin Django une colonne avec le nombre de livres publiés par chaque éditeur, de manière à pouvoir utiliser le tri intégré?
Supposons que j'ai un modèle Book contenant une clé étrangère vers un modèle Publisher.
Comment afficher dans l'admin Django une colonne avec le nombre de livres publiés par chaque éditeur, de manière à pouvoir utiliser le tri intégré?
J'ai eu le même problème (je ne peux pas changer le gestionnaire de mon modèle pour ajouter des annotations ou des jointures lentes). Une combinaison de deux des réponses ici fonctionne. @Andre est vraiment proche, l'administrateur Django prend en charge la modification de l'ensemble de requêtes pour uniquement l'administrateur, alors appliquez la même logique ici, puis utilisez l'attribut admin_order_field. Vous devez toujours ajouter le nouveau champ admin à list_display, bien sûr.
from django.db.models import Count
class EventAdmin(admin.ModelAdmin)
list_display = (..., 'show_artist_count')
def queryset(self, request):
return Event.objects.annotate(artist_count=Count('artists'))
def show_artist_count(self, inst):
return inst.artist_count
show_artist_count.admin_order_field = 'artist_count'
Essaye ça:
faire un nouveau gestionnaire (et agréger avec compter sur le champ de relation livre):
class PublisherManager(models.Manager):
def get_query_set(self):
return super(PublisherManager,self).get_query_set().annotate(pubcount=Count('book'))
trier sur pubcount
:
class Publisher(models.Model):
......
objects = PublisherManager()
class Meta:
ordering = ('pubcount',)
Vous devriez en effet commencer par ajouter:
class PublisherManager(models.Manager):
def get_query_set(self):
return super(PublisherManager,self).get_query_set().annotate(pubcount=Count('book'))
Mais la bonne façon de l'ajouter en tant que champ triable est:
class Publisher(models.Model):
......
objects = PublisherManager()
def count(self):
return self.pubcount
count.admin_order_field = 'pubcount'
Et puis vous pouvez simplement ajouter 'count' à l'attribut list_display du modèle admin dans admin.py
Lincoln B réponse était la bonne façon de faire pour moi.
Au début, je voulais juste un commentaire sur sa solution, mais en fait je me suis retrouvé à la résolution d'un problème légèrement différent. J'avais un administrateur de classe, ce que je voulais "personnaliser" à mes besoins, à savoir l' django-taggit
admin. Dans l'une de mes application de l' admin.py
, j'ai ajouté:
# sort tags by name in admin (count items also possible)
from taggit.admin import TagAdmin
TagAdmin.ordering = ["name"]
# make sortable on item_count:
# 1. function for lookup
def item_count(obj):
"""This takes the item_count from object: didn't work as model field."""
return obj.item_count # not needed: obj.taggit_taggeditem_items.count()
# 2. property in function - admin field name
item_count.admin_order_field = 'item_count'
# 3. queryset override, with count annotation
from django.db.models import Count
TagAdmin.queryset = lambda self, request: super(TagAdmin, self).queryset(request).annotate(item_count=Count('taggit_taggeditem_items'))
# 4. add to list display
TagAdmin.list_display = ["name", item_count]
L'observation intéressant pour moi était que je ne pouvais pas juste d'annoter l' queryset
, et ajouter "item_count"
de list_display
- parce qu'il n'y avait pas d' item_count
méthode de TagAdmin
,, ni une méthode ou le champ de l' Tag
de la classe du modèle (seulement dans l' queryset
).
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.