ComhiomlánúLink to this heading

Chuir an treoir ábhair ar:doc: API teastarbhaithe bunachar sonraí Django síos ar an mbealach is féidir leat ceisteanna Django a úsáid a chruthaíonn, a aisghabhann, a nuashon</topics/db/queries> rú agus a scriosann rudaí aonair. Mar sin féin, uaireanta beidh ort luachanna a dhíorthaítear a aisghabháil trí bhailiúchán rudaí a achoimriú nó a chomhthóiriú. Déanann an treoir ábhair seo cur síos ar na bealaí is féidir luachanna comhiomlána a ghiniúint agus a thabhairt ar ais ag baint

Le linn na treoir seo, déanfaimid tagairt do na samhlacha seo a leanas. Úsáidtear na samhlacha seo chun an fardal do shraith siopaí leabhar ar líne a rianú:

Python
from django.db import models


class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()


class Publisher(models.Model):
    name = models.CharField(max_length=300)


class Book(models.Model):
    name = models.CharField(max_length=300)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    rating = models.FloatField()
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
    pubdate = models.DateField()


class Store(models.Model):
    name = models.CharField(max_length=300)
    books = models.ManyToManyField(Book)

Bileog cheatLink to this heading

Ar deifir? Seo conas ceisteanna comhiomlán coitianta a dhéanamh, ag glacadh leis na samhlacha thuas:

Python console
# Total number of books.
>>> Book.objects.count()
2452

# Total number of books with publisher=BaloneyPress
>>> Book.objects.filter(publisher__name="BaloneyPress").count()
73

# Average price across all books, provide default to be returned instead
# of None if no books exist.
>>> from django.db.models import Avg
>>> Book.objects.aggregate(Avg("price", default=0))
{'price__avg': 34.35}

# Max price across all books, provide default to be returned instead of
# None if no books exist.
>>> from django.db.models import Max
>>> Book.objects.aggregate(Max("price", default=0))
{'price__max': Decimal('81.20')}

# Difference between the highest priced book and the average price of all books.
>>> from django.db.models import FloatField
>>> Book.objects.aggregate(
...     price_diff=Max("price", output_field=FloatField()) - Avg("price")
... )
{'price_diff': 46.85}

# All the following queries involve traversing the Book<->Publisher
# foreign key relationship backwards.

# Each publisher, each with a count of books as a "num_books" attribute.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count("book"))
>>> pubs
<QuerySet [<Publisher: BaloneyPress>, <Publisher: SalamiPress>, ...]>
>>> pubs[0].num_books
73

# Each publisher, with a separate count of books with a rating above and below 5
>>> from django.db.models import Q
>>> above_5 = Count("book", filter=Q(book__rating__gt=5))
>>> below_5 = Count("book", filter=Q(book__rating__lte=5))
>>> pubs = Publisher.objects.annotate(below_5=below_5).annotate(above_5=above_5)
>>> pubs[0].above_5
23
>>> pubs[0].below_5
12

# The top 5 publishers, in order by number of books.
>>> pubs = Publisher.objects.annotate(num_books=Count("book")).order_by("-num_books")[:5]
>>> pubs[0].num_books
1323

Comhiomlánacha a ghiniúint thar QuerySetLink to this heading

Soláthraíonn Django dhá bhealach chun comhiomlán a ghiniúint. Is é an chéad bhealach ná luachanna achoimre a ghiniúint thar ``QuerySet ``iomlán. Mar shampla, abair gur mhaith leat meánphraghas na leabhar go léir atá ar fáil le díol a ríomh. Soláthraíonn comhréir fiosrúcháin Django bealach chun cur síos a dhéanamh ar shraith na leabhar go léir:

Python console
>>> Book.objects.all()

Is é an rud a theastaíonn uainn ná bealach chun luachanna achoimre a ríomh thar na rudaí a bhaineann leis an QuerySet` seo. Déantar é seo trí chlásal ``comhiomlán () ``a chur leis an ``QuerySet:

Python console
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg("price"))
{'price__avg': 34.35}

Tá an ``all () ``iomarcach sa sampla seo, mar sin d'fhéadfaí é seo a shimpliú go:

Python console
>>> Book.objects.aggregate(Avg("price"))
{'price__avg': 34.35}

Déanann an argóint leis an gclásal comhiomlán () ``cur síos ar an luach comhiomlán a theastaíonn uainn a ríomh - sa chás seo, meán an réimse ``praghas ar an tsamhail Leabhar. <aggregation-functions>Is féidir liosta de na feidhmeanna comhiomlána atá ar fáil a fháil in:ref: `QuerySet tagairt `.

Is clásal teirminéil é comhiomlán () ``do `QuerySet a thugann foclóir de phéirí ainmluacha ar ais, nuair a ghairmtear é. Is aitheantóir é an t-ainm don luach comhiomlán; is é an luach an comhiomlán ríomhaithe. Gintear an t-ainm go huathoibríoch ó ainm an réimse agus ón bhfeidhm chomhiomlán. Más mian leat ainm a shonrú de láimh don luach comhiomlán, is féidir leat é sin a dhéanamh tríd an ainm sin a sholáthar nuair a shonraíonn tú an clásal comhiomlán:

Python console
>>> Book.objects.aggregate(average_price=Avg("price"))
{'average_price': 34.35}

Más mian leat níos mó ná comhiomlán amháin a ghiniúint, cuireann tú argóint eile leis an gclásal ``comhiomlán () ``. Mar sin, dá mbeimis ag iarraidh uasphraghas agus íosta na leabhar go léir a fháil amach, eisíomar an cheist:

Python console
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg("price"), Max("price"), Min("price"))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

Comhiomlánacha a ghiniúint do gach mír i QuerySetLink to this heading

Is é an dara bealach chun luachanna achoimre a ghiniúint ná achoimre neamhspleách a ghiniúint do gach réad in a:class: .QuerySet. Mar shampla, má tá liosta leabhair á aisghabháil agat, b'fhéidir gur mhaith leat a fháil amach cé mhéad údar a chuir le gach leabhar. Tá caidreamh go leor ag gach Leabhar leis an Údar; ba mhaith linn achoimre a dhéanamh ar an gcaidreamh seo do gach leabhar sa QuerySet.

Is féidir achoimrí in aghaidh an rud a ghiniúint ag baint úsáide as an gclásal: meth: ~.queryset.annotate. Nuair a shonraítear clásal ``annotate () ``, déanfar anótáil ar gach réad sa ``QuerySet` leis na luachanna sonraithe.

Tá comhréir na n-anótaí seo comhionann leis an gclásal: meth: ~.queryset.aggregate. Déanann gach argóint le ``annotate () ``cur síos ar chomhiomlán atá le ríomh. Mar shampla, chun leabhair a anótáil le líon na n-údar:

Python console
# Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count("authors"))
# Interrogate the first object in the queryset
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
# Interrogate the second object in the queryset
>>> q[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1

Mar is amhlaidh le ``comhiomlán () ``, díorthaítear an t-ainm don anótáil go huathoibríoch ó ainm na feidhme comhiomlán agus ainm an réimse atá á chomhiomlánú. Is féidir leat an t-ainm réamhshocraithe seo a shárú trí ainm a sholáthar nuair a shonraíonn tú an t-anótáil:

Python console
>>> q = Book.objects.annotate(num_authors=Count("authors"))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

Murab ionann agus comhiomlán () ``, `annotate () is clásal teirminéil . Is é QuerySet aschur an chlásal annotate () ``; is féidir an `QuerySet seo a mhodhnú ag baint úsáide as aon oibríocht QuerySet eile, lena n-áirítear filter (), ord_by () `, nó fiú glaonna breise chuig annotate ().

Comhiomlánú iolracha a churLink to this heading

<10060>Comhiomlánú iolracha a chomhcheangal le ``annotate () ``beidh: ticket: `na torthaí míchearta mar úsáidtear comhpháirteanna in ionad fo-cheisteanna:

Python console
>>> book = Book.objects.first()
>>> book.authors.count()
2
>>> book.store_set.count()
3
>>> q = Book.objects.annotate(Count("authors"), Count("store"))
>>> q[0].authors__count
6
>>> q[0].store__count
6

Maidir le formhór na gcomhiomlánaithe, níl aon bhealach ann chun an fhadhb seo a sheachaint, áfach, tá paraiméadar ``difriúil ``ag comhiomlán:class: ~django.db.models.count a d'fhéadfadh cabhrú le:

Python console
>>> q = Book.objects.annotate(
...     Count("authors", distinct=True), Count("store", distinct=True)
... )
>>> q[0].authors__count
2
>>> q[0].store__count
3

Comhcheangail agus comhiomlánaitheLink to this heading

Go dtí seo, déileálamar le comhiomlánaithe thar réimsí a bhaineann leis an tsamhail atá á cheistiú. Mar sin féin, uaireanta bainfidh an luach a theastaíonn uait a chomhiomlánú le samhail a bhaineann leis an tsamhail atá á fhiosrú agat.

Agus an réimse atá le comhiomlánú a shonrú i bhfeidhm chomhiomlán, ligfidh Django duit an chéanna a úsáid: ref: `notáil béim dúbailte <field-lookups-intro>`a úsáidtear agus tú ag tagairt do réimsí gaolmhara i scagairí. Déanfaidh Django ansin láimhseáil le haon chomhcheangail tábla atá ag teastáil chun an luach gaolmhar a aisghabháil

Mar shampla, chun raon praghsanna na leabhar a thairgtear i ngach siopa a fháil, d'fhéadfá an anótáil a úsáid:

Python console
>>> from django.db.models import Max, Min
>>> Store.objects.annotate(min_price=Min("books__price"), max_price=Max("books__price"))

Insíonn sé seo do Django an tsamhail Store a aisghabháil, páirt a ghlacadh (tríd an gcaidreamh go leor) leis an tsamhail ``Leabhar ``, agus comhiomlánú ar réimse praghsanna an tsamhail leabhar chun luach íosta agus uasta a tháirgeadh.

Tá feidhm ag na rialacha céanna maidir leis an gclásal ``comhiomlán () ``. Dá dteastaíonn uait an praghas is ísle agus is airde d'aon leabhar atá ar fáil le díol in aon cheann de na siopaí a fháil, d'fhéadfá an comhiomlán a úsáid:

Python console
>>> Store.objects.aggregate(min_price=Min("books__price"), max_price=Max("books__price"))

Is féidir le slabhraí a bheith chomh domhain agus is gá duit. Mar shampla, chun aois an údair is óige d'aon leabhar atá ar fáil le díol a bhaint, d'fhéadfá an cheist a eisiúint:

Python console
>>> Store.objects.aggregate(youngest_age=Min("books__authors__age"))

Ag leanúint caidrimh ar aisLink to this heading

Ar bhealach cosúil le:ref: lookups-that-span-reachships, is féidir le comhiomlánú agus anótaí ar réimsí samhlacha nó samhlacha a bhaineann leis an gceann atá á fhiosrú agat caidrimh “droim” a bheith san áireamh. Úsáidtear ainm beaga samhlacha gaolmhara agus béim dhúbailte anseo freisin.

Mar shampla, is féidir linn iarraidh ar gach foilsitheoir, a bhfuil anótáil acu lena gcuntair stoc leabhar iomlána faoi seach (tabhair faoi deara conas a úsáidimid `leabhar chun an Foilsitheoir ``-> `Leabhar eochair eachtrach droim a shonrú):

Python console
>>> from django.db.models import Avg, Count, Min, Sum
>>> Publisher.objects.annotate(Count("book"))

(Beidh tréith bhreise ar a dtugtar book__count ag gach Foilsitheoir ``sa `QuerySet` mar thoradh air.)

Is féidir linn an leabhar is sine a iarraidh freisin d'aon cheann de na cinn atá á mbainistiú ag gach foilsitheoir:

Python console
>>> Publisher.objects.aggregate(oldest_pubdate=Min("book__pubdate"))

(Beidh eochair ar a dtugtar 'oldest_pubdate' ag an bhfoclóir mar thoradh air. Mura ndéanfaí aon ainm den sórt sin a shonrú, bheadh sé an book__pubdate__min' sách fada.)

Ní bhaineann sé seo ach le heochracha eachtracha. Oibríonn sé freisin le caidreamh go leor. Mar shampla, is féidir linn gach údar a iarraidh, anótáilte le líon iomlán na leathanaigh ag smaoineamh ar na leabhair go léir atá (co-) údar an t-údar (tabhair faoi deara conas a úsáidimid `leabhar chun an Údar -> Leabhar` a shonrú go leor hop):

Python console
>>> Author.objects.annotate(total_pages=Sum("book__pages"))

(Beidh tréith bhreise ar a dtugtar total_pages ag gach Údar sa QuerySet` mar thoradh air. Mura ndéanfaí aon ainm den sórt sin a shonrú, bheadh sé an `book__pages__sum ``sách fada.)

Nó iarr meánrátáil na leabhar go léir atá scríofa ag údar (í) atá againn ar chomhad:

Python console
>>> Author.objects.aggregate(average_rating=Avg("book__rating"))

(Beidh eochair ar a dtugtar 'average_rating' ag an bhfoclóir mar thoradh air. Mura ndéanfaí aon ainm den sórt sin a shonrú, bheadh sé an book__rating__avg' sách fada.)

Comhiomlánú agus clásail eile ``QuerySet`Link to this heading

scagaire () ``agus ``eisiamh ()Link to this heading

Is féidir le comhiomlán páirt a ghlacadh i scagairí Beidh éifeacht ag aon scagaire () ``(nó ``eisiamh ()) a chuirtear i bhfeidhm ar ghnáthréimsí samhlacha srian ar na rudaí a mheastar lena chomhiomlánú.

Nuair a úsáidtear é le clásal ``annotate () `, tá éifeacht ag scagaire srian ar na rudaí a ríomhtar anótáil dóibh. Mar shampla, is féidir leat liosta anótaithe a ghiniúint de na leabhair go léir a bhfuil teideal acu ag tosú le “Django” ag baint úsáide as an bhfiosrú:

Python console
>>> from django.db.models import Avg, Count
>>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count("authors"))

Nuair a úsáidtear é le clásal ``comhiomlán () ``, tá éifeacht ag scagaire srian ar na rudaí a ríomhtar an comhiomlán orthu. Mar shampla, is féidir leat meánphraghas gach leabhar a ghiniúint le teideal a thosaíonn le “Django” ag baint úsáide as an gceist:

Python console
>>> Book.objects.filter(name__startswith="Django").aggregate(Avg("price"))

Scagadh ar anótaíLink to this heading

Is féidir luachanna anótaithe a scagadh freisin. Is féidir an t-ailias don anótáil a úsáid i gclásail scagaire () ``agus ``eisiamh () ar an mbealach céanna le haon réimse samhail eile.

Mar shampla, chun liosta leabhair a ghiniúint a bhfuil níos mó ná údar amháin acu, is féidir leat an cheist a eisiúint:

Python console
>>> Book.objects.annotate(num_authors=Count("authors")).filter(num_authors__gt=1)

Gineann an cheist seo tacar torthaí anótaithe, agus ansin gineann sé scagaire bunaithe ar an anótáil sin.

Má theastaíonn dhá anótáil uait le dhá scagaire ar leithligh is féidir leat an argóint scagair a úsáid le haon chomhiomlán. Mar shampla, chun liosta údair a ghiniúint le líon leabhair ardrátáilte:

Python console
>>> highly_rated = Count("book", filter=Q(book__rating__gte=7))
>>> Author.objects.annotate(num_books=Count("book"), highly_rated_books=highly_rated)

Beidh na tréithe num_books agus highly_rated_books ag gach Údar sa tacar torthaí. Féach freis:ref: comhiomlánú coinníollach.

Ordú clásail anótáit () ``agus ``scagaire ()Link to this heading

Agus ceist casta á fhorbairt ina mbaineann clásail annotate () ``agus `scagaire () araon, tabhair aird ar leith ar an ord ina gcuirtear na clásail i bhfeidhm ar an QuerySet.

Nuair a chuirtear clásal annotate () ``i bhfeidhm ar cheist, ríomhtar an t-anótáil thar staid na fiosrúcháin suas go dtí an pointe ina n-iarrtar an t-anótáil. Is é an tionchar praiticiúil a bhaineann leis seo nach oibríochtaí comutaitheacha iad ``filter () ``agus ``annotate ().

A thugtar:

  • Tá dhá leabhar ag Foilsitheoir A le rátálacha 4 agus 5.

  • Tá dhá leabhar ag Foilsitheoir B le rátálacha 1 agus 4.

  • Tá leabhar amháin ag Foilsitheoir C le rátáil 1.

Seo sampla leis an comhiomlán Count:

Python console
>>> a, b = Publisher.objects.annotate(num_books=Count("book", distinct=True)).filter(
...     book__rating__gt=3.0
... )
>>> a, a.num_books
(<Publisher: A>, 2)
>>> b, b.num_books
(<Publisher: B>, 2)

>>> a, b = Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count("book"))
>>> a, a.num_books
(<Publisher: A>, 2)
>>> b, b.num_books
(<Publisher: B>, 1)

Tugann an dá cheist liosta foilsitheoirí a bhfuil leabhar amháin ar a laghad acu le rátáil níos mó ná 3.0, dá bhrí sin tá foilsitheoir C eisiata.

Sa chéad cheist, bíonn an anótáil roimh an scagaire, mar sin níl aon éifeacht ag an scagaire ar an anótáil. <combining-multiple-aggregations>Teastaíonn Distinct=True chun a:ref: fabht ceiste` a sheachaint.

Áireamh sa dara ceist líon na leabhar a bhfuil rátáil níos mó ná 3.0 acu do gach foilsitheoir. Tá an scagaire roimh an anótáil, mar sin cuireann an scagaire srian ar na rudaí a mheastar agus an anótáil á ríomh.

Seo sampla eile leis an comhiomlán Avg:

Python console
>>> a, b = Publisher.objects.annotate(avg_rating=Avg("book__rating")).filter(
...     book__rating__gt=3.0
... )
>>> a, a.avg_rating
(<Publisher: A>, 4.5)  # (5+4)/2
>>> b, b.avg_rating
(<Publisher: B>, 2.5)  # (1+4)/2

>>> a, b = Publisher.objects.filter(book__rating__gt=3.0).annotate(
...     avg_rating=Avg("book__rating")
... )
>>> a, a.avg_rating
(<Publisher: A>, 4.5)  # (5+4)/2
>>> b, b.avg_rating
(<Publisher: B>, 4.0)  # 4/1 (book with rating 1 excluded)

Iarrann an chéad cheist meán-rátáil leabhair uile foilsitheora do fhoilsitheoirí a bhfuil leabhar amháin ar a laghad acu le rátáil níos mó ná 3.0. Iarrann an dara ceist meán rátálacha leabhar foilsitheora le haghaidh na rátálacha sin níos mó ná 3.0 amháin.

Tá sé deacair a chur in iúl conas a aistríonn an ORM ceisteanna casta go ceisteanna SQL mar sin nuair a bhíonn amhras ort, iniúchadh ar an SQL le `str (queryset.query) ``agus scríobh neart tástálacha.

``ord_by () ``Link to this heading

Is féidir anótaí a úsáid mar bhunús le haghaidh ordú. Nuair a shainmhíníonn tú clásal ``order_by () , is féidir leis na comhiomláin a sholáthraíonn tú tagairt a dhéanamh d'aon ainm a shainmhínítear mar chuid de chlásal ``annotate () sa cheist.

Mar shampla, chun “QuerySet” de leabhair a ordú de réir líon na n-údar a chuir leis an leabhar, d'fhéadfá an cheist seo a leanas a úsáid:

Python console
>>> Book.objects.annotate(num_authors=Count("authors")).order_by("num_authors")

``luachanna () ``Link to this heading

De ghnáth, gintear anótaí ar bhonn in aghaidh an réada - tabharfaidh ``QuerySet` anótáilte toradh amháin ar ais do gach réad sa ``QuerySet` bunaidh. Mar sin féin, nuair a úsáidtear clásal ``luachanna () ``chun srian a chur ar na colúin a chuirtear ar ais sa tacar torthaí, tá an modh chun anótaí a mheas beagán difriúil. In ionad toradh anótaithe a thabhairt ar ais do gach toradh sa “QuerySet” bunaidh, déantar na torthaí bunaidh a ghrúpáil de réir na gcomhcheangail uathúla de na réimsí a shonraítear sa chlásal ``luachanna () ``. Cuirtear anótáil ar fáil ansin do gach grúpa uathúil; ríomhtar an t-anótáil thar gach ball den ghrúpa.

Mar shampla, smaoinigh ar cheist údair a dhéanann iarracht meánrátáil leabhar a scríobh gach údar a fháil amach:

Python console
>>> Author.objects.annotate(average_rating=Avg("book__rating"))

Tabharfaidh sé seo toradh amháin ar ais do gach údar sa bhunachar sonraí, anótáilte lena meánrátáil leabhar.

Mar sin féin, beidh an toradh beagán difriúil má úsáideann tú clásal ``luachanna () ``:

Python console
>>> Author.objects.values("name").annotate(average_rating=Avg("book__rating"))

Sa sampla seo, déanfar na húdair a ghrúpáil de réir ainm, mar sin ní gheobhaidh tú ach toradh anótaithe do gach ainm údair uath* uath*. Ciallaíonn sé seo má tá beirt údar agat leis an ainm céanna, déanfar a dtorthaí a chumasc i dtoradh amháin in aschur na fiosrúcháin; ríomhfar an meán mar an meán thar na leabhair a scríobh an dá údar.

Ordú clásail anótáit () ``agus `luachanna ()Link to this heading

Mar is amhlaidh leis an gclásal scagaire () ``, an t-ord ina gcuirtear clásail ``annotate () agus luachanna () `i bhfeidhm ar cheist suntasach. Má théann an clásal ``luachanna () ``roimh an `annotate ()`, ríomhfar an t-anótáil ag baint úsáide as an ngrúpáil a thuairiscítear leis an gclásal ``luachanna () ``.

Mar sin féin, má théann an clásal annotate () ``roimh an gclásal ``luachanna (), ginfear na nótaí thar an tacar fiosrúcháin iomlán. Sa chás seo, ní chuireann an clásal `luachanna () ``srian ach ar na réimsí a ghintear ar aschur.

Mar shampla, má aisiompaímid ord na clásal luachanna () ``agus ``annotate () ónár sampla roimhe seo:

Python console
>>> Author.objects.annotate(average_rating=Avg("book__rating")).values(
...     "name", "average_rating"
... )

Tabharfaidh sé seo toradh uathúil amháin anois do gach údar; áfach, ní thabharfar ach ainm an údair agus an anótáil meán_rating` ar ais sna sonraí aschuir.

Ba chóir duit a thabhairt faoi deara freisin go bhfuil meán_rating san áireamh go sainráite sa liosta luachanna atá le tabhairt ar ais. Tá sé seo ag teastáil mar gheall ar ordú na clásal luachanna () ``agus ``annotate ().

Má théann an clásal luachanna () ``roimh an gclásal ``annotate (), cuirfear aon anótaí go huathoibríoch leis an tacar torthaí. Mar sin féin, má chuirtear an clásal luachanna () ``i bhfeidhm tar éis an chlásal ``annotate ()`, ní mór duit an colún comhiomlán a chur san áireamh go sainráite.

Idirghníomhaíocht le ``order_by () ``Link to this heading

Úsáidtear réimsí a luaitear sa chuid order_by () ``de tacar fiosrúcháin agus na sonraí aschuir á roghnú, fiú mura sonraítear iad a shlí eile sa ghlao ``values (). Úsáidtear na réimsí breise seo chun torthaí “cosúil leis” a ghrúpáil le chéile agus is féidir leo a dhéanamh go bhfuil sraitheanna torthaí comhionanna ar leithligh Taispeánann sé seo, go háirithe, agus rudaí á chomhaireamh.

Mar shampla, cuir i gcás go bhfuil samhail mar seo agat:

Code
from django.db import models


class Item(models.Model):
    name = models.CharField(max_length=10)
    data = models.IntegerField()

Más mian leat a chomhaireamh cé mhéad uair atá gach luach `sonraí ``ar leith le feiceáil i tacar ceisteanna ordaithe, b'fhéidir go dtriail a bhaint as seo:

Code
items = Item.objects.order_by("name")
# Warning: not quite correct!
items.values("data").annotate(Count("id"))

... a ghrúpáidh na rudaí Mír ``de réir a luachanna coitianta ``sonra agus ansin líon na luachanna id a chomhaireamh i ngach grúpa. Ach amháin nach n-oibreoidh sé go leor. Beidh páirt ag an ordú trí ainm ``sa ghrúpáil freisin, mar sin déanfar an ceist seo a ghrúpáil de réir péirí (sonraí, ainm) ``ar leithligh, nach é an rud atá uait. Ina áit sin, ba cheart duit an tacar fiosrúcháin seo a thógáil:

Code
items.values("data").annotate(Count("id")).order_by()

... aon ordú sa cheist a ghlanadh. D'fhéadfá ordú freisin trí, abair, `sonraí ``gan aon éifeachtaí díobhálacha, ós rud é go bhfuil ról ag imirt sin cheana féin sa cheist.

Tá an t-iompar seo mar an gcéanna leis an gcáipéisíocht Queryset dag:meth: ~django.db.models.query.queryset.Distinct agus tá an riail ghinearálta mar an gcéanna: de ghnáth ní theastaíonn uait colúin bhreise a imirt sa toradh, mar sin soiléir an t-ordú, nó ar a laghad cinnte go bhfuil sé srianta do na réimsí sin a roghnaíonn tú freisin i nglao ``values () `.

Anótaí a chomhiomlánúLink to this heading

Is féidir leat comhiomlán a ghiniúint freisin ar thoradh anótála. Nuair a shainmhíníonn tú clásal ``comhiomlán () ``, is féidir leis na comhiomláin a sholáthraíonn tú tagairt a thabhairt d'aon ainm a shainmhínítear mar chuid de chlásal ``annotate () `sa cheist.

Mar shampla, más mian leat meánlíon na n-údar in aghaidh an leabhair a ríomh déanann tú anótáil ar dtús an tacar leabhar le comhaireamh na n-údair, ansin comhiomlánú an údair sin, ag tagairt don réimse anótála:

Python console
>>> from django.db.models import Avg, Count
>>> Book.objects.annotate(num_authors=Count("authors")).aggregate(Avg("num_authors"))
{'num_authors__avg': 1.66}

Comhiomlánú ar cheisteanna nó grúpaí folamhLink to this heading

<aggregate-default>Nuair a chuirtear comhiomlánú i bhfeidhm ar shraith fiosrúcháin nó grúpáil folamh, déanann an toradh réamhshocraithe ar a pharaiméadar: ref: réamhshocraithe', de ghnáth ``None`. Tarlaíonn an t-iompar seo toisc go bhfilleann feidhmeanna comhiomlánacha NULL nuair a fhaigheann an ceist forghníomhaithe

Is féidir leat luach tuairisceáin a shonrú tríd an argóint: ref: default <aggregate-default>`a sholáthar don chuid is mó de na comhiomlánaithe. <aggregate-default>Mar sin féin, ós rud é nach dtacaíonn: class: `~django.db.models.count leis an argóint: ref: default `, fillfidh sé ``0` i gcónaí le haghaidh ceisteanna folmha nó grúpaí.

Mar shampla, ag glacadh leis nach bhfuil web in ainm ar aon leabhar, ag ríomh an praghas iomlán don tacar leabhar seo ar ais None ós rud é nach bhfuil aon sraitheanna comhoiriúnaithe ann chun an comhiomlán:class: ~django.db.Models.sum a ríomh ar:

Python console
>>> from django.db.models import Sum
>>> Book.objects.filter(name__contains="web").aggregate(Sum("price"))
{"price__sum": None}

Mar sin féin, is féidir an argóint:ref: default <aggregate-default>`a shocrú agus tú ag glaoch ar: class: `~django.db.models.sum chun luach réamhshocraithe difriúil a thabhairt ar ais mura féidir aon leabhair a aimsiú:

Python console
>>> Book.objects.filter(name__contains="web").aggregate(Sum("price", default=0))
{"price__sum": Decimal("0")}

Faoin gcochall, cuirtear an argóint:ref: default <aggregate-default>`i bhfeidhm tríd an bhfeidhm chomhiomlán a fhilleadh le:class: `~django.db.models.functions.coalesce.

Aggregating with MySQL ONLY_FULL_GROUP_BY enabledLink to this heading

When using the values() clause to group query results for annotations in MySQL with the ONLY_FULL_GROUP_BY SQL mode enabled, you may need to apply AnyValue if the annotation includes a mix of aggregate and non-aggregate expressions.

Take the following example:

Python console
>>> from django.db.models import F, Count, Greatest
>>> Book.objects.values(greatest_pages=Greatest("pages", 600)).annotate(
...     num_authors=Count("authors"),
...     pages_per_author=F("greatest_pages") / F("num_authors"),
... ).aggregate(Avg("pages_per_author"))

This creates groups of books based on the SQL column GREATEST(pages, 600). One unique group consists of books with 600 pages or less, and other unique groups will consist of books with the same pages. The pages_per_author annotation is composed of aggregate and non-aggregate expressions, num_authors is an aggregate expression while greatest_page isn't.

Since the grouping is based on the greatest_pages expression, MySQL may be unable to determine that greatest_pages (used in the pages_per_author expression) is functionally dependent on the grouped column. As a result, it may raise an error like:

Pytb
OperationalError: (1055, "Expression #2 of SELECT list is not in GROUP BY
clause and contains nonaggregated column 'book_book.pages' which is not
functionally dependent on columns in GROUP BY clause; this is incompatible
with sql_mode=only_full_group_by")

To avoid this, you can wrap the non-aggregate expression with AnyValue.

Python console
>>> from django.db.models import AnyValue, F, Count, Greatest
>>> Book.objects.values(
...     greatest_pages=Greatest("pages", 600),
... ).annotate(
...     num_authors=Count("authors"),
...     pages_per_author=AnyValue(F("greatest_pages")) / F("num_authors"),
... ).aggregate(Avg("pages_per_author"))
{'pages_per_author__avg': 532.57143333}

Other supported databases do not encounter the OperationalError in the example above because they can detect the functional dependency. In general, AnyValue is useful when dealing with select list columns that involve non-aggregate functions or complex expressions not recognized by the database as functionally dependent on the columns in the grouping clause.