2012-06-22 3 views
0

У меня проблемы с prefetch_related Django.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 Backend: 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]: [] 

ответ

1

Yikes. Выяснил проблему. Некоторое время назад была ошибка, когда prefetch_related не работала, если поле pk вашей модели было нетекстовым (например, целое число). Я вручную заплата эту строку:

vals = rel_obj_cache.get(instance_attr_val, []) 

ближе к концу query.py, чтобы выглядеть следующим образом:

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

Это фиксированная моя проблема. Но с тех пор я предполагаю, что проблема была решена формально по-другому, и теперь мой перевод в Юникоде заставил поиск словаря возвратить пустой список (в основном, обратный исходной ошибке).

Итак, просто пришлось отменить мой ручной патч, и теперь он отлично работает. Неудивительно, что я не мог найти кого-либо другого с этой проблемой!