0

Django の prefetch_related に問題があります。

これが私のモデルです。

class Terrain(models.Model):
    name = models.CharField(max_length=255)

class Route(models.Model):
    name = models.CharField(max_length=255)
    terrains = models.ManyToManyField(Terrain)

prefetch_related を使用すると、次のようになります。

>>> Route.objects.all()[0].terrains.all()
[<Terrain: Beach>]
>>> Route.objects.all().prefetch_related('terrains')[0].terrains.all()
[]

ここで何が間違っているのか分かりますか?

Python バージョン 2.7 Django バージョン 1.4 DB バックエンド: SQLite (MySQL でも試しましたが、同じ結果)

そして、ここに (IPython コンソールからの) クエリのデバッグがいくつかあるので、そこで何が起こっているかを見ることができます。

In [11]: Route.objects.all().prefetch_related('terrains')[0].terrains.all()
DEBUG 2012-06-22 20:10:09,569 util (0.000) SELECT "asdf_route"."id", "asdf_route"."name" FROM "asdf_route" LIMIT 1; args=()
DEBUG 2012-06-22 20:10:09,571 util (0.000) SELECT ("asdf_route_terrains"."route_id") AS "_prefetch_related_val", "asdf_terrain"."id", "asdf_terrain"."name" FROM "asdf_terrain" INNER JOIN "asdf_route_terrains" ON ("asdf_terrain"."id" = "asdf_route_terrains"."terrain_id") WHERE "asdf_route_terrains"."route_id" IN (1); args=(1,)
Out[11]: []
4

1 に答える 1

1

うわぁ。問題を理解しました。少し前に、モデルの pk フィールドが非テキスト (整数など) の場合に prefetch_related が機能しないというバグがありました。この行に手動でパッチを適用しました:

vals = rel_obj_cache.get(instance_attr_val, [])

query.py の終わり近くで、次のようになります。

vals = rel_obj_cache.get(unicode(instance_attr_val), [])

それは私の問題を解決しました。しかし、それ以来、問題は別の方法で正式に解決されたと思います。現在、Unicode キャストにより、その辞書検索で空のリストが返されていました (基本的には元のバグの逆です)。

そのため、手動パッチを元に戻す必要がありましたが、今では正常に機能しています。この問題を抱えている人を他に見つけることができなかったのも不思議ではありません!

于 2012-06-22T23:15:35.650 に答える