3

Django が過剰なクエリを実行しないようにプリフェッチ関連を使用しようとしていますが、継承のあるモデルでは機能しません。

問題は、継承を使用してモデルをトラバースすると、モデル インスタンスがキャッシュされず、SQL クエリが発行されることです。

これが Django のバグなのか、それとも間違った使い方をしているのかはわかりません。

これが私のコードです:

models.py:

class ParentBase(models.Model): pass

class Parent(models.Model): pass

class ParentWithBase(ParentBase): pass

class Child(models.Model):
    parent = models.ForeignKey('Parent')
    parent_with_base = models.ForeignKey('ParentWithBase')

テストケース:

def test_prefetch_error(self):
    Child.objects.create(parent = Parent.objects.create(), parent_with_base = ParentWithBase.objects.create())
    child = Child.objects.prefetch_related('parent','parent_with_base').all()[0]
        with self.assertNumQueries(0):
            child.parent # This works just fine - no queries are emitted
        with self.assertNumQueries(0):
            child.parent_with_base # TEST FAILS HERE - since one query is emitted
4

1 に答える 1

0

https://code.djangoproject.com/ticket/19420によると、この結果がキャッシュされないという事実は、Django 1.5 で修正されました。

ただし、この場合、select_related代わりにprefetch_related. 単に一方を他方に置き換えるだけで、テストは成功します。

select_relatedForeignKey 関係に従います。prefetch_related多対多および多対一の関係がある場合は、関係ごとに個別のルックアップを行い、Python で「結合」を行うため、より便利です。を使用select_relatedすると、結合を伴う 1 つの DB 呼び出しのみがprefetch_related行われますが、その処理を実行する必要があると想定されているため、すぐに複数の呼び出しが行われます。

于 2013-04-23T11:43:06.450 に答える