2010-03-13 3 views
3

Je cherche quelque chose comme ce qui suit:Django: Grouper par?

previous_invoices = Invoice.objects.filter(is_open=False) 
            .order_by('-created') 
            .group_by('user') 

mais group_by() n'existe pas ...

Ce trouverait la facture plus récemment fermé pour chaque utilisateur.

Cette aggregation API semble vous permettre de faire des choses comme ça pour les comptes et les sommes, mais je n'ai pas besoin d'un compte ou d'une somme ou quoi que ce soit, je veux réellement les objets de facture!

+0

est la chose * selected * même définie lors de l'utilisation de group by? Je m'attendrais à ce qu'il donne des résultats différents selon l'implémentation de sql ... – user3012759

+0

@ user3012759 Non. La commande se passe après le groupement, l'enregistrement que vous récupérez dans ce groupe est indéfini. Il m'a fallu un certain temps pour vraiment comprendre cela. ['ONLY_FULL_GROUP_BY'] (https://dev.mysql.com/doc/refman/5.7/fr/sql-mode.html#sqlmode_only_full_group_by) doit être activé par défaut IMO afin que vous ne commettiez pas cette erreur. – mpen

+0

Hey @mpen J'ai ajouté une tentative plus récente de répondre. Vous voulez jeter un coup d'oeil? –

Répondre

1

Option 1:

Bien qu'un group_by() n'existe pas dans Django, vous pouvez essayer de travailler autour de récupérer la facture plus récemment fermé pour chaque utilisateur en utilisant la méthode latest() et filtre pour un utilisateur ainsi:

previous_invoices = Invoice.objects.filter(user=my_user, is_open=False) 
            .latest('created') 

Pour les anciennes versions de Django étaient latest() n'existe pas, la requête ressemblera à ceci:

previous_invoices = Invoice.objects.filter(user=my_user, is_open=False) 
            .order_by('-created')[0] 

Option 2:

Si vous voulez absolument créer les effets d'un group_by, alors vous un créer un manuellement comme indiqué dans la réponse acceptée ici: Django GROUP BY field value.

  1. Utilisez .values_list() avec flat=True pour obtenir une liste des valeurs existantes dans votre base de données (si vous ne connaissez pas à l'avance).Utilisez également .distinct() pour elimintae les valeurs en double que nous ne nous soucions pas pour ceux:

    value_list = MyModel.objects.values_list(
        'interesting_field', flat=True 
    ).distinct() 
    
  2. maintenant itérer value_list et remplir votre dictionnaire:

    group_by_value = {} 
    for value in value_list: 
        group_by_value[value] = MyModel.objects.filter(interesting_field=value) 
    

Maintenant group_by_value dictionnaire contient comme clés distincts: valeurs dans votre interesting_field et en tant que valeurs les objets de l'ensemble de quincailleries, chacun contenant les entrées de MyModel avec interesting_field=a value from value_list.


Note:

Il existe cette bibliothèque django-group-by qui prétend ajouter un group_by() sur Django vous pouvez vérifier.

2

Il y a this page from 2007 qui l'a piraté en django, mais ce serait sans intérêt puisque pré 1.1 a de toute façon un groupe non documenté. Mais this thread from a year ago semble avoir quelques idées. Essentiellement:

Django intentionnellement n'expose pas "GROUP BY" ou quelque chose comme ça, en l'ORM. Bien que le fait que nous sommes sur un backend de stockage relationnel fuit parfois à travers, l'API ORM est assez SQL-agnostique. Au lieu de cela, nous exposons des pièces particulières de fonctionnalités qui se trouvent être mis en œuvre en utilisant « GROUP BY » quand il est transformé en SQL (et pourrait bien être mis en œuvre par un tout autre ensemble des fées magiques avec une base de système de stockage différent).

Voir aussi les mentions de l'utilisation extra, et aussi les moyens magiques dans lesquels que peut échouer. Bonne chance.