# dokumentasi Django 2.0.8

# Pengumpulan

Panduan topik pada Django's database-abstraction API menggambarkan cara dimana anda dapat menggunakan permintaan Django yang membuat, mengambil, memperbaharui dan menghapus obyek tersendiri. Bagaimanapun, terkadang anda akan butuh mengambil nilai yang berasal oleh meringkas atau*mengumpulkan* kumpulan dari obyek. Topik panduan ini menggambarkan cara yang mengumpulkan nilai-nilai dapat dibangkitkan dan dikembalikan menggunakan permintaan Django.

Sepanjang panduan ini, kami akan mengacu ke model berikut. Model-model ini digunakan untuk melacak inventaris untuk rangkaian dari toko buku daring:

    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)
        num_awards = models.IntegerField()

    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)
        registered_users = models.PositiveIntegerField()

## Lembar curang

Terburu-buru? Ini adalah bagaimana melakukan permintaan pengumpulan umum, menganggap model diatas:

    # 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.
    >>> from django.db.models import Avg
    >>> Book.objects.all().aggregate(Avg('price'))
    {'price__avg': 34.35}

    # Max price across all books.
    >>> from django.db.models import Max
    >>> Book.objects.all().aggregate(Max('price'))
    {'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

## Membangkitkan pengumpulan terhadap `QuerySet`

Django menyediakan dua cara membangkitkan pengumpulan. Cara pertama adalah membangkitkan nilai ringkasan terhadap keseluruhan `QuerySet`. Sebagai contoh, katakan anda ingin menghitung rata-rata harga dari semua buku tersedia untuk dijual. Sintaksis permintaan Django menyediakan sarana untuk menggambarkan kumpulan dari semua buku:

    >>> Book.objects.all()

Apa kami butuhkan adalah cara menghitung ringkasan nilai terhadap obyek yang memiliki `QuerySet` ini. Ini diselesaikan dengan menambah sebuah klausa `aggregate()` kedalam `QuerySet`:

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

`all()` berulang di contoh ini, jadi ini dapat disederhanakan menjadi:

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

Argumen pada klausa `aggregate()` menggambarkan nilai pengumpulan yang kami ingin hitung - dalam kasus ini, rata-rata dari bidang `price` pada model `Book`. Sebuah daftar dari fungsi pengumpulan yang tersedia dapat ditemukan di QuerySet reference.

`aggregate()` adalah klausa terminal untuk sebuah `QuerySet` yang, ketika dipanggil, mengembalikan sebuah kamus dari pasangan nama-nilai. Nama adalah sebuah penciri untuk nilai pengumpulan; nilai adalah pengumpulan yang dihitung. Nama adalah otomatis dibangkitkan dari nama dari bidang dan fungsi pengumpulan. Jika anda ingin manual menentukan nama untuk nilai pengumpulan, anda dapat melakukannya dengan menyediakan nama itu ketika anda menentukan klausa pengumpulan:

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

Jika anda ingin membangkitkan lebih dari satu pengumpulan, anda hanya menambah argumen lain ke klusa `aggregate()`. Jadi, jika kami juga ingin mengetahui harga maksimal dan minimal dari semua buku, kami akan menerbitkan permintaan:

    >>> 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')}

## Membangkitkan pengumpulan untuk setiap barang di `QuerySet`

Cara kedua membangkitkan ringkasan nilai adalah membangkitkan sebuah ringkasan berdiri sendiri untuk setiap obyek dalam sebuah `QuerySet`. Sebagai contoh, jika anda sedang mengambil sebuah daftar buku, anda mungkin ingin mengetahui seberapa banyak penulis membantu setiap buku. Setiap buku mempunyai hubungan many-to-many dengan Author; kami ingin meringkaskan hubungan ini untuk setiap buku dalam `QuerySet`.

Ringkasan per-obyek dapat dibangkitkan menggunakan klausa `annotate()`. Ketika sebuah klausa `annotate()` ditentukan, stiap obyek dalam `QuerySet` akan dicatat dengan nilai yang ditentukan.

Sintaksis untuk catatan ini mirip pada yang digunakan untuk klausa `aggregate()`. Setiap argumen pada `annotate()` menggambarkan sebuah pengumpulan yang untuk dihitung. Sebagai contoh, untuk mencatat buku dengan sejumlah penulis:

    # 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

Seperti `aggregate()`, nama untuk catatan otomatis berasal dari nama dari fungsi pengumpulan dan nama dari bidang sedang dikumpulkan. Anda dapat menimpa nama awalan ini dengan menyediakan sebuah nama lain ketika anda menentukan catatan:

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

Tidak seperti `aggregate()`, `annotate()` adalah bukan klausa terminal. Keluaran dari klausa `annotate()` adalah sebuah `QuerySet`; `QuerySet` ini dapat dirubah menggunakan apapun selain operasi `QuerySet`, termasuk `filter()`, `order_by()`, atau bahkan tambahan panggilan pada `annotate()`.

### Memadukan banyak pengumpulan

Memadukan banyak pengumpulan dengan `annotate()` akan yield the wrong results karena join digunakan daripada sub permintaan:

    >>> 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

Untuk kebanyakan pengumpulan, tidak ada jalan menghindari masalah ini, bagaimanapun, pengumpulan `Count` mempunai sebuah parameter `distinct` yang mungkin membantu:

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

Jika ragu, periksa permintaan SQL!

Untuk memahami apa yang terjadi di permintaan anda, pertimbangkan memeriksa sifat `query` dari `QuerySet` anda.

## Gabung dan kumpulkan

Sejauh ini, kami telah berurusan dengan pengumpulan terhadap bidang yang milik ke model sedang diminta. Bagaimanapun, terkadang nilai anda ingin kumpulkan akan milik ke model yang terkait ke model anda sedang meminta.

Ketika anda menentukan bidang untuk dikumpulkan dalam sebuah fungsi pengumpulan, Django akan mengizinkan anda menggunakan double underscore notation sama yang digunakan ketika mengacu ke bidang terkait dalam penyaring. Django akan kemudian menangani gabungan table apapun yang dibutuhkan untuk mengambil dan mengumpulkan nilai terkait.

Sebagai contoh, untuk menemukan jangkauan harga dari buku ditawarkan disetiap toko, anda dapat menggunakan catatan:

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

Ini memberitahu Django untuk mengambil model `Store`, gabung (melalui hubungan many-to-many) dengan model `Book`, dan dikumpulkan pada bidang harga dari model buku untuk menghasilkan sebuah nilai minimal dan maksimal.

Aturan sama berlaku pada klausa `aggregate()`. Jika anda ingin mengetahui harga terendah dan tertinggi dari buku apapun yang tersedia untuk dijual di toko apapun, anda dapat menggunakan pengumpulan:

    >>> Store.objects.aggregate(min_price=Min('books__price'), max_price=Max('books__price'))

Ikatan join dapat sedalam seperti anda minta. Sebagai contoh, untuk mengeluarkan umur dari penulis termuda dari buku apapun yang tersedia untuk dijual, anda dapat menerbitkan permintaan:

    >>> Store.objects.aggregate(youngest_age=Min('books__authors__age'))

### Mengikuti hubungan kebelakang

Dalam sebuah cara mirip pada Pencarian yang menjangkau hubungan, pengumpulan dan catatan pada bidang dari model atau model yang terkait ke satu anda sedang meminta dapat menyertakan lintasan hubungan "reverse". Nama huruf kecil dari model terkait dan garis bawah ganda digunakan disini juga.

Sebagai contoh, kami dapat meminta untuk semua penerbit, dicatat dengan masing-masing jumlah penghitung stok buku (catat bahwa kami menggunakan `'book'` untuk menentukan `Publisher` -> `Book` membalikkan lompatan foreign key):

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

(Setiap `Publisher` dalam menghasilkan `QuerySet` akan mempunyai sebuah atribut tambahan disebut `book__count`.)

Kami dapat juga meminta untuk buku tertua dari setiap dari itu dikelola oleh setiap penerbit:

    >>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate'))

(Hasil kamus akan mempunyai sebuah kunci dipanggil `'oldest_pubdate'`. Jika tidak ada nama lain seperti itu telah ditentukan, itu akan agak panjang `'book__pubdate__min'`.)

Ini tidak berlaku hanya pada foreign key. Itu juga bekerja dengan hubungan many-to-many. Sebagai contoh, kami dapat meminta untuk setiap penulis, dicatat dengan jumlah nomor dari halaman mempertimbangkan semua buku penulis mempunyai penulis(-bersama) (catat bagaimana menggunakan `'book'` untuk menentukan `Author` -> `Book` membalikkan lompatan many-to-many):

    >>> Author.objects.annotate(total_pages=Sum('book__pages'))

(Setiap `Author` dalam menghasilkan `QuerySet` akan mempunyai sebuah atribut tambahan dipanggil `total_pages`. Jika tidak ada nama lain itu, itu akan menjadi agak panjang `book__pages__sum`.)

Atau minta untuk penilaian rata-rata dari semua buku ditulis oleh penulis kami punyai pada berkas:

    >>> Author.objects.aggregate(average_rating=Avg('book__rating'))

(Hasil kamus akan mempunyai sebuah kunci dipanggil `'average_rating'`. Jika tidak ada nama lain seperti itu telah ditentukan, itu akan agak panjang `'book__rating__avg'`.)

## Pengumpulan dan klausa `QuerySet` lain

### `filter()` dan `exclude()`

Pengumpulan dapat juga ikut serta dalam penyaring. `filter()` (atau``exclude()``) apapun berlaku pada bidang model biasa akan mempunyai pengaruh dari membatasi obyek yang dianggap untuk pengumpulan.

Ketika digunakan dengan sebuah klausa `annotate()`, sebuah penyaring mempunyai pengaruh dari membatasi obyek untuk dimana sebuah catatan dihitung. Sebagai contoh, anda dapat membangkitkan daftar dari semua buku yang mempunyai sebuah judul dimulai dengan "Django"" menggunakan permintaan:

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

Ketika digunakan dengan sebuah klausa `aggregate()`, sebuah penyaring mempunyai pengaruh dari membatasi obyek untuk dimana sebuah pengumpulan dihitung. Sebagai contoh, anda dapat membangkitkan rata-rata harga dari semua buku yang mempunyai sebuah judul dimulai dengan "Django"" menggunakan permintaan:

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

#### Penyaringan pada keterangan

Nilai dicatat dapat juga disaring. Nama lain untuk catatan dapat digunaan dalam klausa `filter()` dan `exclude()` di cara sama seperti bidang model lainnya apapun.

Sebagai contoh, untuk membangkitkan sebuah daftar buku yang mempunyai lebih dari satu penulis, anda dapat menerbitkan permintaan:

    >>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1)

Permintaan ini membangkitkan sebuah kumpulan hasil keterangan, dan kemudian membangkitkan sebuah penyaring berdasarkan pada keterangan itu.

Jika anda butuh dua keterangan dengan dua penyaring terpisah anda dapat menggunakan argumen `filter` dengan pengumpulan apapun. Sebagai contoh, untuk membangkitkan daftar dari penulis dengan jumlah peringkat buku tertinggi:

    >>> highly_rated = Count('books', filter=Q(books__rating__gte=7))
    >>> Author.objects.annotate(num_books=Count('books'), highly_rated_books=highly_rated)

Setiap `Author` dalam kumpulan hasil akan memiliki atribut-atribut `num_books` dan `highly_rated_books`.

Memilih diantara `filter` dan `QuerySet.filter()`

Hidnari menggunakan argumen `filter` dengan keterangan atau pengumpulan tunggal. Itu lebih efesien menggunakan `QuerySet.filter()` untuk tidak menyertakan baris. Argumen pengumpulan `filter` hanya berguna ketika menggunakan dua atau lebih pengumpulan terhadap hubungan sama dengan keadaan berbeda.

Changed in Django 2.0:

Argumen `filter` telah ditambahkan pada pengumpulan.

#### Urutan dari klausa `annotate()` dan `filter()`

Ketika mengembangkan sebuah permintaan rumit yang melibatkan kedua klausa `annotate()` dan `filter()`, berikan perhatian khusus pada urutan dimana klausa diberlakukan pada `QuerySet`.

Ketika sebuah klausa `annotate()` diberlakukan pada sebuah permintaan, catatan dihitung terhadap keadaan dari permintaan sampai titik dimana catatan diminta. Impliaksi praktik dari ini adalah bahwa `filter()` dan `annotate()` bukan operasi komutatif.

Diberikan:

- Penerbit A mempunyai dua buku dengan nilai 4 dan 5.
- Penerbit B mempunyai dua buku dengan nilai 1 dan 4.
- Penerbit C mempunyai satu buku dengan penilaian 1.

Ini adalah sebuah contoh dengan pengumpulan `Count`:

    >>> 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)

Kedua permintaan mengembalikan sebuah daftar dari penerbit yang mempunyai setidaknya satu buku dengan penilaian melebihi 3.0, karenanya penerbit C tidak disertakan.

Dalam permintaan pertama, catatan mendahului penyaring, jadi penyaring tidak mempunyai pengaruh pada catatan. `distinct=True` dibutuhkan untuk menghindari query bug.

Permintaan kedua menghitung jumlah buku yang mempunyai nilai melebihi 3.0 untuk setiap penerbit. Penyaring ini mendahului catatan, jadi batasan penyaring obyek dianggap ketika menghitung catatan.

Ini adalah sebuah contoh lain dengan pengumpulan `Avg`:

    >>> 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)

Permintaan pertama meminta untuk rata-rata penilaian dari semua penerbit buku untuk penerbit yang mempunyai setidaknya satu buku ketika penilaian melebihi 3.0. Permintaan kedua meminta untuk rata-rata dari penilaian buku penerbit untuk hanya mereka penilaian melebihi 3.0.

Itu adalah sangat sulit memahami bahwa ORM akan menterjemahkan queryset rumit kedalam permintaan SQL ketika dalam keraguan, periksa SQL dengan `str(queryset.query)` dan tulis jumlah besar percobaan.

### `order_by()`

Catatan dapat digunakan sebagai dasar untuk pengurutan. Ketika anda menentukan sebuah klausa `order_by()`, pengumpulan anda sediakan dapat mengacu nama lain apapun ditentukan sebagai bagian dari sebuah klausa `annotate()` dalam permintaan.

Sebagai contoh, untuk mengurutkan `QuerySet` dari buku dengan jumlah dari pengarang yang memiliki bantuan pada buku, anda dapat menggunakan permintaan berikut:

    >>> Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')

### `values()`

Biasanya, catatan dibangkitkan pada dasar per-obyek - sebuah `QuerySet` dicatat akan mengembalikan satu hasil untuk setiap obyek dalam `QuerySet` asli. Bagaimanapun, ketika sebuah klausa `values()` digunakan untuk membatasi kolom yang dikembalikan dalam kumpulan hasil, metode untuk menilai catatan adak sedikit berbeda. Sebagai gantinya mengembalikan sebuah hasil dicatat untuk setiap hasil dalam `QuerySet` asli, hasil asli dikelompokkan menurut pada perpaduan unik dari bidang-bidang ditentukan dalam klausa `values()`. Sebuah catatam kemudian disediakan untuk setiap kelompok unik; catatan dihitung terhadap semua anggota dari kelompok.

Untuk setiap contoh, pertimbangkan sebuah permintaan penulis yang berusaha menemukan rata-rata penilaian dari buku ditulis oleh setiap penulis.

    >>> Author.objects.annotate(average_rating=Avg('book__rating'))

Ini akan mengembalikan satu hasil untuk setiap penulis di basisdata, diberikan keterangan dengan nilai buku rata-rata mereka.

Bagaimanapun, hasil akan sedikit berbeda jika anda menggunakan kalusa `values()`:

    >>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))

Dalam contoh ini, penulis akan dikelompokkan berdasarkan nama, jadi anda akan hanya mendapatkan sebuah hasil dicatata untuk setiap nama penulis unik. Ini berarti jika anda mempunyai dua penulis dengan nama sama, hasil mereka akan digabung kedalam hasil tunggal di keluaran dari permintaan; rata-rata akan dihitung sebagai rata-rata terhadap buku ditulis oleh kedua penulis.

#### Urutan dari klausa `annotate()` dan `values()`

Seperti klausa `filter()`, urutan dimana klausa `annotate()` dan `values()` diberlakukan pada sebuah permintaan adalah signifikan. Jika klausa `values()` mendahului `annotated()`, catatan akan dihitung menggunakan pengelomppokan digambarkan oleh klausa `values()`.

Bagaimanapun, jika klausa `annotate()` mendahului klausa `values()`, catatan akan dibangkitkan terhadap keseluruhan kumpulan permintaan. Dalam kasus ini, klausa `values()` hanya membatasi bidang yang dibangkitkan pada keluaran.

Sebagai contoh, jika kami membalikkan urutan dari klausa `values()` dan `annotate()` dari contoh kami sebelumnya:

    >>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')

Ini akan sekarang menghasilkan hasil unik untuk setiap penulis; bagaimanapun, hanya nama penulis dan catatan `average_rating` akan dikembalikan dalam data keluaran.

Anda harus juga catat bahwa `average_rating` telah jelas disertakan dalam daftar dari nilai-nilai untuk dikembalikan. Ini dibutuhkan karena dari urutan dari klausa `values()` dan `annotate()`.

Jika klausa `values()` mendahului klausa `annotate()`, setiap catatan akan otomatis ditambahkan ke kumpulan hasil. Bagaimanapun, jika klausa `values()` diberlakukan setelah klausa `annotate()`, anda butuh jelas menyertakan kolom pengumpulan.

#### Interaksi dengan pengurutan awalan atau `order_by()`

Bidang-bidang yang disebut di bagian `order_by()` dari sebuah queryset (atau yang digunakan di pengurutan awalan pada sebuah model) digunakan ketika memilih data keluaran, bahkan jika mereka tidak sebaliknya ditentukan di panggilan `values()`. Bidang tambahan ini digunakan untuk mengelompokkan hasil "like" bersama-sama dan mereka dapat membuat sebaliknya baris hasil mirip muncul untuk dipesahkan. Ini menunjukkan, khususnya, ketika menghitung hal-hal.

Berdasarkan cara contoh, seharusnya anda mempunyai model seperti ini:

    from django.db import models

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

        class Meta:
            ordering = ["name"]

Bagian terpenfting disini adalah pengurutan awalan pada bidang `name`. Jika anda ingin menghitung seberapa banyak kali setiap perbedaan nilai `data` muncul, anda mungkin mencoba ini:

    # Warning: not quite correct!
    Item.objects.values("data").annotate(Count("id"))

...yang akan mengelompokkan obyek `Item` berdasarkan nilai-nilai `data` umum mereka dan menghitung nomro dari nilai-nilai `id` dalam setiap kelompok, Kecuali itu tidak akan bekerja. Pengurutan awalan oleh `name` akan juga bermain bagian dalam pengelompokan, jadi permintaan ini akan dikelompokkan berdasarkan perbedaan pasangan `(data, name)`, yang tidak apa anda inginkan. Malahan, anda harus membangun queryset ini:

    Item.objects.values("data").annotate(Count("id")).order_by()

...membersihkan pengurutan apapun di permintaan. Anda dapat juga mengurutkan berdasarkan, katakan, `data` tanpa pengaruh berbahaya apapun, sejak itu sudah bermain sebuah peran dalam permintaan.

Perilaku ini adalah sama seperti dicatat dalam dokumentasi queryset untuk `distinct()` dan aturan umum adalah sama: biasanya anda tidak ingin kolom tambahan bermain bagian dalam hasil, jadi bersihkan pengurutan, atau setidaknya pastikan itu terbatas hanya bidang-bidang tersebut anda juga pilih dalam sebuah panggilan `values()`.

Catatan

Anda mungkin layak bertanya mengapa Django tidak memidnahkan kolom tidak ada hubungannya untuk anda. Alasan utama adalah ketetapan dengan distinct()`` dan tempat lain: Django tidak pernah memindahkan pengurutan yang anda telah tentukan (dan kami tidak dapat merubah perilaku metode lain tersebut, ketika itu akan melanggar kebijakan Keseimbangan API kami).

### Pengumpulan catatan

Anda dapat juga membangkitkan sebuah pengumpulan pada hasil dari sebuah catatan. Ketika anda menentukan sebuah klausa `aggregate()`, pengumpulan anda sediakan dapat mengacu setiap nama lain ditentukan sebagai bagian dari sebuah klausa `annotated()` dalam permintaan.

Sebagai contoh, jika anda ingin menjumlahkan angka rata-rata dari penulis per buku anda pertama membubuhi catatan kumpulan buku dengan jumlah penulis, lalu kumpulkan jumlah penulis itu, mengacu bidang membubuhi catatan

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