7

あるフィールドで並べ替えるだけでなく、そのフィールドの一意の値ごとに個別の QuerySet (または辞書、リストなど) を取得するような方法でデータベースにクエリを実行したいと考えています。以下の例が役立つことを願っています。

のようなモデルを仮定します

Class Person(models.Model):
   first_name = models.CharField()
   last_name = models.CharField

Person.objects.all().order_by('last_name') を呼び出すと、単一の長い QuerySet が得られます。代わりに、一意の last_name ごとに個別のリストが必要です。したがって、last_name="Smith" を持つすべての Person に対して 1 つのリストと、last_name="Nguyen" を持つすべての Person に対して別のリストが作成されます。

明らかに、データベース内の last_names がどのようなものになるか、何人の人が共通の last_name を共有するかを前もって知ることはできません。djangoでこれを行うための高速、効率的、または自動の方法はありますか?または、1つの大きなクエリセットを取得した後、自分でデータを処理する必要がありますか?

4

3 に答える 3

13

samy のコードは正しいですが、かなり非効率的です。n+1 回のクエリを実行します (n は一意の姓の数です)。とにかく、テーブル内のすべてのオブジェクトを取得するので、一度に取得することもできます。代わりにこれを使用してください:

from collections import defaultdict
person_dict = defaultdict(list)
persons = Person.objects.all()
for person in persons:
    person_dict[person.last_name].append(person)
于 2012-07-09T08:52:35.083 に答える
8

regroupタグを見てください。

{% regroup persons by last_name as surname_list %}

<ul>
{% for last_name in surname_list %}
    <li>{{ last_name.grouper }}
    <ul>
        {% for person in last_name.list %}
          <li>{{ person.last_name }}, {{ person.first_name }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

(このコードはテストされていません。ドキュメントを読んで、問題があれば自分で修正してください)

于 2012-07-09T02:43:19.140 に答える
1

すべての一意の姓を取得できます。

from django.db.models import Count
...
last_names = Person.objects.values('last_name').annotate(Count('last_name')) # This will return all the unique last_names
values = dict( ((last_name['last_name'], Person.objects.all().filter(last_name = last_name['last_name'])) for last_name in last_names if last_name['last_name__count']) )
# This will create a dictionary where the keys are all the unique names and the values are querysect of all the values that have that lastname

Daniel-Roseman の言う通り、かなり効率が悪いので、微調整バージョンを用意します ...

from collections import defaultdict
values = defaultdict(list)
_ = map(lambda person: values[person.last_name].append(person), Person.objects.all())

_ = ...そのため、端末にすべてを出力しないことに注意してくださいNone;)

于 2012-07-09T02:47:17.197 に答える