Django 1.2.1 и load_related_m2m

by Larin

Интро

Думаю, многие из нас занимались оптимизацие загрузки данных из полей ManyToManyField. Задача для оптимизации проста: есть коллекция объектов с некоторым полем (полями) М2М. Необходимо выбрать данные для поля М2М одним запросом, т.е. не выполнять для каждого объекта из коллекции отдельный запрос, по загрузке однотипных данных.

Думаю, многие для этого писали собственные функции, я же пользовался load_related_m2m, найденной когда-то толи на djbook.ru, толи на сайте Ивана Сагалаева.

И вот при обновлении до Django 1.2.1 при вызове функции load_related_m2m, появилась ошибка: ‘DatabaseWrapper’ object is not callable

Исправляем

Очевидно, произошло это из-за смены интефейсов класса django.db.models.sql.Query. Для возобновления работоспособности необходимо изменить буквально пару строк:

Код


# -*- coding: utf-8 -*-
from django.db.models.sql.constants import LOOKUP_SEP
from django.db.models import sql
from django.db import connection                                               

def load_related_m2m(object_list, field):                                      

    select_fields = ['pk']
    related_field = object_list.model._meta.get_field(field)
    related_model = related_field.rel.to
    cache_name = 'all_%s' % field                                              

    for f in related_model._meta.local_fields:
        select_fields.append('%s%s%s' % (field, LOOKUP_SEP, f.column))         

    query = sql.Query(object_list.model)
    query.add_fields(select_fields)
    query.add_filter(('pk__in', [obj.pk for obj in object_list]))

    related_dict = {}
    cursor = connection.cursor()
    cursor.execute(str(query))

    for row in cursor.fetchall():
        if row[2]:
            related_dict.setdefault(row[0], []).append(related_model(*row[1:]))

    for obj in object_list:
        try:
            setattr(obj, cache_name, related_dict[obj.pk])
        except KeyError:
            setattr(obj, cache_name, [])

    return object_list

З.Ы.

А лето выдалось жаркое. Такое чувство, что в тени +40 )