2

たとえば、次のモデルがあります。

class Person(models.Model):
    name = models.CharField(max_length=20)
    employer = models.CharField(max_length=20)

class Car(models.Model):
    person = models.ForeignKey(Person)
    name = models.CharField(max_length=10)
    model = models.CharField(max_length=10)
    ...

特定の車を所有しているすべての人を取得したい:

people = Person.objects.filter(car__name="Toyota")

今、私はこれらの人々に自分の車についての詳細を書き留めたいと思います. 私がすることができます:

for person in people:
   ...
   cars = person.car_set.filter(name="Toyota")
   ...

しかし、それは再びデータベースにヒットしました。どうすればこれを回避できますか? これをもっと簡単にする方法はありますか?

4

3 に答える 3

3

車名を決めるときは、まず車と関係者を選択

cars = Car.objects.select_related("person").filter(name="Toyota").order_by("person")

これで、toyota という名前のすべての車と、その車の person である order_by person ができました。

次に、python itertools.groupby を使用して、このリストを各人にグループ化します

from itertools import groupby
for k, g in groupby(cars, lambda x: x.person):
       person = k
       cars = list(g)

その反復では、人物と彼の車 (名前は「トヨタ」) があります。発生するクエリは 1 つだけで、キャッシュされた情報に対して次の操作が実行されることに気付くでしょう。

于 2011-07-10T04:49:01.177 に答える
0

チェックアウトselect_related()、私は以前にそれを使用して、複数のモデルにまたがる多くの小さなクエリを1つの大きなクエリに変換しました:https ://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related

を事前に入力することで機能するQuerySetため、へのアクセスcar_setはすでに存在し、新しいクエリは発生しません。

于 2011-07-08T17:54:20.713 に答える
0

追加のデータベースヒットを回避する方法があるとは思いません。あまりにも多くのクエリを作成することが心配な場合は、次のようなことを試すことができます。

from collections import defaultdict

cars = Car.objects.filter(**kwargs).selected_related('person')
owners = defaultdict(list)

for car in cars:
    owners[car.person].append(car)

これは、関連するすべての車とその関係者に関するデータを選択する 1 つのクエリのみである必要があります。

于 2011-07-08T18:04:29.503 に答える