QuerySet
de Django a deux méthodes, annotate
et aggregate
. La documentation indique que:
Contrairement à l'agrégat (), annotate () n'est pas une clause terminale. La sortie de la clause annotate () est un QuerySet.
Y a-t-il une autre différence entre eux? Sinon, pourquoi existe-t-il aggregate
?
Je me concentrerais sur les exemples de requêtes plutôt que sur votre citation de la documentation. Aggregate
calcule les valeurs de l'ensemble de requêtes entier. Annotate
calcule les valeurs récapitulatives pour chaque élément dans le jeu de requêtes.
>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}
Renvoie un dictionnaire contenant le prix moyen de tous livres dans l'ensemble de requêtes.
>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1
q
est l'ensemble de requêtes des livres, mais chaque livre a été annoté avec le nombre d'auteurs.
C'est la principale différence, mais les agrégats fonctionnent également à une échelle plus grande que les annotations. Les annotations sont intrinsèquement liées aux éléments individuels d'un ensemble de requêtes. Si vous exécutez une annotation Count
sur quelque chose comme un champ plusieurs-à-plusieurs, vous obtiendrez un décompte distinct pour chaque membre de l'ensemble de requêtes (en tant qu'attribut ajouté). Si vous deviez faire la même chose avec une agrégation, cependant, elle essaierait de compter chaque relation sur chaque membre du jeu de requêtes, même les doublons, et de le renvoyer comme une seule valeur.
Aggregate Aggregate génère des valeurs de résultat (résumé) sur un QuerySet entier. Les agrégats opèrent sur l'ensemble de lignes pour obtenir une valeur unique de l'ensemble de lignes (par exemple, la somme de tous les prix de l'ensemble de lignes). L'agrégat est appliqué à l'ensemble du QuerySet et il génère des valeurs de résultat (récapitulatif) sur un QuerySet entier.
Dans le modèle:
class Books(models.Model):
name = models.CharField(max_length=100)
pages = models.IntegerField()
price = models.DecimalField(max_digits=5, decimal_places=3)
En coquille:
>>> Books.objects.all().aggregate(Avg('price'))
# Above code will give the Average of the price Column
>>> {'price__avg': 34.35}
Annotate Annotate génère un résumé indépendant pour chaque objet dans un QuerySet. (On peut dire qu'il itère chaque objet dans un QuerySet et applique une opération)
Dans le modèle:
class Video(models.Model):
name = models.CharField(max_length=52, verbose_name='Name')
video = models.FileField(upload_to=document_path, verbose_name='Upload
video')
created_by = models.ForeignKey(User, verbose_name='Created by',
related_name="create_%(class)s")
user_likes = models.ManyToManyField(UserProfile, null=True,
blank=True, help_text='User can like once',
verbose_name='Like by')
En vue:
videos = Video.objects.values('id', 'name','video').annotate(Count('user_likes',distinct=True)
En vue, il comptera les likes pour chaque vidéo