Есть ли у Клиента 1 2 питомца, а у Клиента 2 1 питомец?
Если это так, это будет означать, что Pet.full_name
или что-то еще, что вы делаете в цикле отображения питомца, пытается получить доступ к данным соответствующего клиента. ORM в Django не использует идентификационную карту , поэтому для доступа к внешнему ключу Клиента из любого из ваших объектов Pet потребуется повторное нажатие на базу данных для получения этого Клиента.
P.S. select_related
не окажет никакого влияния на данные, которые вы используете в этом сценарии, поскольку оно только следует отношениям внешнего ключа, но отношение «домашнее животное-клиент» много-к-одному.
Обновление: если вы хотите избежать необходимости изменять логику в Pet.full_name
или выполнять вместо этого указанную логику в шаблоне для этого случая, вы можете изменить способ получения дескриптора для каждого Домашние животные Клиента для того, чтобы предварительно заполнить кэш ForeignKey для каждого Домашнего животного с его Клиентом:
class Client(models.Model):
# ...
def get_pets(self):
for pet in self.pets.all():
setattr(pet, '_client_cache', self)
yield pet
... где 'client'
часть '_client_cache'
- это любое имя атрибута, которое используется в классе Pet для ForeignKey для клиента Pet. Это использует преимущества того, как Django реализует доступ к объектам, связанным с ForeignKey, используя свой класс SingleRelatedObjectDescriptor
, который ищет этот атрибут кэша перед запросом к базе данных.
Результирующее использование шаблона:
{% for pet in client.get_pets %}
...
{% endfor %}