Saya meminta model:
Members.objects.all()
Dan itu kembali:
Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2-Shop
Sean, Manager, X2-Shop
Apa yang saya inginkan adalah mengetahui cara Django terbaik untuk mem- group_by
burn query ke database saya, seperti:
Members.objects.all().group_by('designation')
Tentu saja itu tidak berhasil. Saya tahu kita bisa melakukan beberapa trik django/db/models/query.py
, tetapi saya hanya ingin tahu bagaimana melakukannya tanpa menambal.
python
django
django-models
cukup keras
sumber
sumber
Members.objects.filter(date=some_date).values('designation').annotate(dcount=Count('designation'))
Members.objects.order_by('disignation').values('designation').annotate(dcount=Count('designation'))
Solusi mudah, tetapi bukan cara yang tepat adalah dengan menggunakan SQL mentah :
Solusi lain adalah dengan menggunakan
group_by
properti:Anda sekarang dapat mengulangi variabel hasil untuk mengambil hasil Anda. Catatan yang
group_by
tidak didokumentasikan dan dapat diubah dalam versi Django yang akan datang.Dan ... mengapa Anda ingin menggunakannya
group_by
? Jika Anda tidak menggunakan agregasi, Anda dapat menggunakanorder_by
untuk mencapai hasil yang sama.sumber
Anda juga dapat menggunakan
regroup
tag template untuk dikelompokkan berdasarkan atribut. Dari dokumen:Terlihat seperti ini:
Ini juga berfungsi pada
QuerySet
s saya percaya.sumber: https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#regroup
sunting: perhatikan bahwa
regroup
tag tidak berfungsi seperti yang Anda harapkan jika daftar kamus Anda tidak diurutkan kunci. Ini bekerja berulang. Jadi, sortir daftar Anda (atau set kueri) dengan kunci kerapu sebelum meneruskannya keregroup
tag.sumber
Anda perlu melakukan SQL khusus seperti yang dicontohkan dalam cuplikan ini:
SQL khusus melalui subquery
Atau di manajer khusus seperti yang ditunjukkan dalam dokumen Django online:
Menambahkan metode Manajer tambahan
sumber
Django tidak mendukung grup gratis berdasarkan permintaan . Saya mempelajarinya dengan cara yang sangat buruk. ORM tidak dirancang untuk mendukung hal-hal seperti apa yang ingin Anda lakukan, tanpa menggunakan SQL kustom. Anda terbatas pada:
cr.execute
kalimat (dan parsing buatan tangan dari hasilnya)..annotate()
(grup dengan kalimat dilakukan dalam model anak untuk .annotate (), dalam contoh-contoh seperti mengagregasi lines_count = Hitung ('baris'))).Melalui queryset
qs
Anda dapat meneleponqs.query.group_by = ['field1', 'field2', ...]
tetapi berisiko jika Anda tidak tahu permintaan apa yang Anda edit dan tidak memiliki jaminan bahwa itu akan berfungsi dan tidak merusak internal objek QuerySet. Selain itu, ini adalah API internal (tidak berdokumen) yang tidak boleh Anda akses langsung tanpa risiko kode tidak lagi kompatibel dengan versi Django yang akan datang.sumber
Ada modul yang memungkinkan Anda untuk mengelompokkan model Django dan masih bekerja dengan QuerySet di hasilnya: https://github.com/kako-nawao/django-group-by
Sebagai contoh:
'book / books.html'
Perbedaan dengan
annotate
/aggregate
basic Django queries adalah penggunaan atribut dari bidang terkait, misalnyabook.author.last_name
.Jika Anda membutuhkan PK dari instance yang telah dikelompokkan bersama, tambahkan anotasi berikut:
CATATAN:
ArrayAgg
adalah fungsi spesifik Postgres, tersedia mulai Django 1.9 dan seterusnya: https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/aggregates/#arrayaggsumber
values
metode. Kurasa untuk tujuan yang berbeda.values
adalah SQLselect
whilegroup_by
adalah SQLgroup by
(seperti namanya ...). Mengapa downvote? Kami menggunakan kode tersebut dalam produksi untuk mengimplementasikangroup_by
pernyataan kompleks .group_by
"sebagian besar berperilaku seperti metode nilai-nilai, tetapi dengan satu perbedaan ..." Doc tidak menyebutkan SQLGROUP BY
dan use case yang disediakannya tidak menyarankan itu ada hubungannya dengan SQLGROUP BY
. Saya akan menarik mundur suara ketika seseorang telah membuat ini jelas, tetapi dokter itu benar-benar menyesatkan.values
, saya menemukan saya merindukan ituvalues
sendiri berfungsi seperti GROUP BY. Ini adalah kesalahanku. Saya pikir ini lebih mudah untuk digunakanitertools.groupby
daripada django-group-by ini ketikavalues
tidak mencukupi.group by
dari atas denganvalues
panggilan sederhana -dengan atau tanpaannotate
dan tanpa mengambil semuanya dari database. Saran Andaitertools.groupby
untuk pekerjaan untuk dataset kecil tetapi tidak untuk beberapa ribu dataset yang mungkin ingin Anda halaman. Tentu saja, pada saat itu Anda harus memikirkan indeks pencarian khusus yang berisi data yang sudah disiapkan (sudah dikelompokkan).The dokumen mengatakan bahwa Anda dapat menggunakan nilai-nilai kelompok queryset tersebut.
Anda dapat menemukan semua buku dan mengelompokkannya berdasarkan nama menggunakan kode ini:
Anda dapat menonton beberapa lembar cheet di sini .
sumber
Jika saya tidak salah, Anda dapat menggunakan, apapun-query-set .group_by = [' bidang ']
sumber
pertama, Anda perlu mengimpor Sum lalu ..
sumber