Кэширование результатов запроса Django для вызовов __unicode__, которые ссылаются на связанные объекты - PullRequest
1 голос
/ 20 декабря 2009

У меня есть следующие модели:

class Territory(models.Model):
    name = models.CharField(max_length=30)
    power = models.ForeignKey(Power, null=True, blank=True)
    is_supply = models.BooleanField()

class Subregion(models.Model):
    territory = models.ForeignKey(Territory)
    subname = models.CharField(max_length=10, blank=True)
    sr_type = models.CharField(max_length=1, choices=SUBREGION_CHOICES)
    init_unit = models.BooleanField()
    borders = models.ManyToManyField("self", null=True, blank=True)

    def __unicode__(self):
        if self.subname:
            return u'%s (%s)' % (self.territory.name, self.subname)
        else:
            return u'%s [%s]' % (self.territory.name, self.sr_type)

Проблема заключается в том, что при рендеринге ModelFormSet, каждая форма которого имеет 3 ModelChoiceFields, содержащий все 120 Subregions, для каждого Subregion в каждом виджете создается отдельный запрос SELECT. Согласно моим журналам Postgres, генерируется более 1000 запросов для простого набора форм из 3 форм, что заметно влияет на время загрузки страницы.

Итак, есть ли разумный способ сделать один большой запрос, который будет кэшировать всю информацию, которая нужна Subregion.__unicode__()?

1 Ответ

1 голос
/ 20 декабря 2009

Вы пытались использовать select_related () ? Это поможет вам с дополнительными поисками для территорий.имя. Границы будут пропущены, потому что по умолчанию select_related () не следует внешним ключам, где null = True. Вы можете попробовать явно указать имена связанных объектов, если вам также нужно получить границы: Subregion.objects.select_related('territory', 'borders').all().

Возьмите это для вращения в ./manage.py shell вашего приложения и посмотрите, помогает ли select_related ():

>>> from django import db
>>> db.reset_queries()
>>> Subregion.objects.all()
# ...
>>> len(db.connection.queries)
# some big number
>>> db.reset_queries()
>>> Subregion.objects.select_related().all()
# ...
>>> len(db.connection.queries)
# a smaller number
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...