Самый эффективный способ получить пользователя с профилем пользователя в Django

В Django при рекомендуемой настройке экземпляр UserProfile связан OneToOneField со своим экземпляром User.

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    data = ...

Каков наиболее эффективный способ внутри представления для получения как пользователя, так и профиля? Могу ли я выполнить внутренний запрос соединения select_related(), чтобы получить оба объекта с одним обращением к базе данных? Или это всегда сводится к двум отдельным вызовам? Возможно, промежуточное программное обеспечение аутентификации Django извлекает экземпляр пользователя еще до вызова представления ... кто-нибудь знает?


person Simon Steinberger    schedule 15.07.2012    source источник
comment
Чтобы предоставить более подробную информацию: профиль можно получить с помощью request.user.userprofile или request.user.get_profile(). Однако оба приводят к двум обращениям к базе данных. Мой вопрос: можем ли мы свести это только к одному внутреннему запросу соединения, используя select_related... и если да, то более ли это эффективно, чем обычно?   -  person Simon Steinberger    schedule 15.07.2012


Ответы (1)


Профиль пользователя можно получить с помощью get_profile().

См. документацию: https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

person Köver    schedule 15.07.2012
comment
Django где-то упоминает, что get_profile кэширует свой результат, но это верно для всех таких запросов. Поэтому я действительно не вижу преимущества по сравнению с user.userprofile. Но что меня действительно сбивает с толку, так это то, что при использовании обоих, user.get_profile и user.userprofile, в одном и том же шаблоне, база данных попадает дважды. Так что до сих пор я постоянно придерживаюсь user.userprofile. В любом случае, оба метода получения профиля приводят к 2 обращениям к базе данных: 1x пользователь + 1x профиль. Вызов select_related делает это в ОДНОМ внутреннем соединении. Это возможно и выгодно? - person Simon Steinberger; 15.07.2012