Вот два примера моделей 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 %}
Этот пример фактически выполняет дополнительный запрос для каждого человека в наборе запросов лиц во время рендеринга шаблона.
Есть ли способ сделать это всего одним запросом или хотя бы выполнить менее одного дополнительного запроса на человека? Может быть, есть другой способ разработать это, чтобы вообще избежать этой проблемы.
Я думал о добавлении BooleanField в Person и о необходимости обновления этого поля при каждом сохранении или удалении питомца. Это действительно правильный путь?
Кроме того, у меня уже есть должная настройка memcached, поэтому такие запросы выполняются только в том случае, если результаты еще не кэшированы. В первую очередь я хочу удалить запросы для еще большей оптимизации.