Как уменьшить количество запросов в методе has_relation модели django?

Вот два примера моделей Django. Обратите особое внимание на метод has_pet.

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

    def has_pet(self):
        return bool(self.pets.all().only('id'))

class Pet(models.Model):
    name = models.CharField(max_length=255)
    owner = models.ForeignKey(Person, blank=True, null=True, related_name="pets")

Проблема в том, что метод has_pet всегда генерирует запрос. Если вы сделаете что-то вроде этого.

p = Person.objects.get(id=1)
if p.has_pet():
    ...

Тогда вы действительно будете выполнять дополнительный запрос, чтобы проверить, есть ли у одного человека домашнее животное. Это большая проблема, если вам нужно проверить несколько человек. Он также будет генерировать запросы, если используется в шаблонах, подобных этому.

{% for person in persons %}
    {% if person.has_pet %}
        {{ person.name }} owns a pet
    {% else %}
        {{ person.name }} is petless
    {% endif %}
{% endfor %}

В этом примере фактически будет выполняться дополнительный запрос для каждого человека в наборе запросов people во время рендеринга шаблона.

Есть ли способ сделать это с помощью всего одного запрос или хотя бы менее одного дополнительного запроса на человека? Возможно, есть другой способ спроектировать это, чтобы полностью избежать проблемы.

Я подумал о добавлении BooleanField в Person и обновлении этого поля при сохранении или удалении питомца. Это действительно правильный путь?

Кроме того, я уже правильно настроил memcached, поэтому эти запросы выполняются только в том случае, если результаты еще не кэшированы. Я хочу в первую очередь удалить запросы для еще большей оптимизации.

7
задан Apreche 2 June 2011 в 00:16
поделиться