2010-05-14 4 views
2

je les modèles suivants (simplifié):Django Groupement de requêtes

class Donation(models.Model): 
    entry_date = models.DateTimeField() 

class Category(models.Model): 
    name = models.CharField() 

class Item(models.Model): 
    donation = models.ForeignKey(Donation) 
    category = models.ForeignKey(Category) 

Je suis en train d'afficher le nombre total d'éléments, par catégorie, regroupés par l'année du don.

J'ai essayé ceci:

Donation.objects.extra(select={'year': "django_date_trunc('year', 
    %s.entry_date)" % Donation._meta.db_table}).values('year', 
    'item__category__name').annotate(items=Sum('item__quantity')) 

Mais je reçois une erreur de terrain sur item__category__name.

J'ai aussi essayé:

Item.objects.extra(select={"year": "django_date_trunc('year', 
    entry_date)"}, tables=["donations_donation"]).values("year", 
    "category__name").annotate(items=Sum("quantity")).order_by() 

Ce qui me fait généralement ce que je veux, mais le nombre de quantité d'articles est multiplié par le nombre d'enregistrements de dons.

Des idées? Fondamentalement, je veux afficher ceci:

 
2010 
    - Category 1: 10 items 
    - Category 2: 17 items 

2009 
    - Category 1: 5 items 
    - Category 3: 8 items 

Répondre

0

Cet autre poste ressemble à ce que vous cherchez:

Django equivalent for count and group by

Selon votre version de Django, vous pouvez ou ne peut pas être en mesure d'utiliser quand même.

+0

Je suis sur Django 1.1.1 - J'aurais dû le mentionner. Je peux faire la requête "Éléments par catégorie" comme répondue plus bas dans ce fil très bien, ce que je ne peux pas comprendre comment faire est de le faire à travers trois modèles - Articles par catégorie regroupés par date de don. C'est le troisième composant que je suis perdu. – Matt

+0

@matt Les requêtes django sont conçues pour être flexibles, mais il arrive parfois que vous ne puissiez pas utiliser une requête django pour effectuer le travail. Dans ce cas, vous pouvez envisager d'utiliser la solution SQL directe. Ce serait probablement plus lisible aussi à ce stade. http://docs.djangoproject.com/fr/dev/topics/db/sql/#topics-db-sql – dlamotte

+0

J'avais peur de ça. Maintenant, pour comprendre le SQL brut pour cette requête;) – Matt

0

Je me rends compte que vous avez probablement déjà écrit votre SQL brut, mais ce qui suit est venu à l'esprit quand j'ai vu la façon dont vous souhaitez afficher vos données:

Si tout va bien le faire au niveau du modèle que vous pourriez être en mesure d'utiliser de manière stratégique l'étiquette regroup et le filtre de longueur.

Regrouper prend une « liste d'objets semblables » si un queryset pourrait fonctionner très bien, mais la documentation montre une liste de dictionnaires, donc je l'ai utilisé des valeurs ici:

item_listing = Item.objects.values('category__name', 'donation__entry_date') 
# use your favourite method to extract the year information into a key in item_listing 
item_listing = ... 

maintenant dans le modèle, Quelque chose comme:

<ul> 
{% for year_group in item_listing %} 
    <li>{{ year_group.grouper }} 
    <ul> 
     {% regroup year_group.list by category__name as category_listing %} 
     {% for category_group in category_listing %} 
     <li> 
     Category: {{ category_group.grouper }} 
     Count: {{ category_group.list|length }} 
     </li> 
     {% endfor %} 
    </ul> 
    </li> 
{% endfor %} 
</ul> 

Je ne suis pas sûr si le tag de regroupement niche bien comme ça (ne l'ai pas essayé). De plus, je n'ai aucune idée de comment fonctionne bien le regroupement si vous avez beaucoup de données, mais là encore, il y a toujours la mise en cache ...

Si vous décidez de l'utiliser, assurez-vous de prendre note de la commande gotcha mentionné dans les documents de regroupement.