-
Привет.
А есть ли у кого-нибудь идеи, как можно избавиться от запросов к базе каждый раз при обращении к любому профилю пользователя? Вот выбираются комментарии к посту, пользователи автоматом выцепляются с помощью select_related. А профили потом выдёргиваются каждый отдельно. Генерируя по запросу на каждый (!) комментарий. Т.е. даже повторяющиеся профили создают отдельные запросы.
Не могу придумать, как бы это красиво побороть. Идей ни у кого нету? -
реализовать свой get_profile() и цеплять его к User
-
Я в Cicero сделал своего наследника queryset'а, который одним запросом вытягивает также и все профили:
Но сейчас я все больше думаю, что это сложно, а вместо этого можно просто ссылаться из комментариев прямо на профиль, а не на пользователя. И тогда select_related будет тянуть и профили, а от них и пользователей.class ArticleQuerySet(QuerySet):
def _get_data(self):
update_profiles = self._result_cache is None and self._select_related
if update_profiles:
profile_select = dict((Profile._meta.db_table + '_' + f.attname, Profile._meta.db_table + '.' + f.attname) for f in Profile._meta.fields)
self._select.update(profile_select)
self._tables.extend([Profile._meta.db_table])
self._where.extend(['%s.%s = %s.%s' % (Profile._meta.db_table, Profile._meta.pk.attname, User._meta.db_table, User._meta.pk.attname)])
result = super(ArticleQuerySet, self)._get_data()
if update_profiles:
for article in result:
data = dict((f.attname, getattr(article, Profile._meta.db_table + '_' + f.attname)) for f in Profile._meta.fields)
article.cicero_profile = Profile(**data)
return result -
У меня, естественно, всё через get_profile и сделано (немного вру, но значения не имеет).
Свой - ты имеешь в виду, что там что-то дополнительно делать? Что? -
Но сейчас я все больше думаю, что это сложно, а вместо этого можно просто ссылаться из комментариев прямо на профиль, а не на пользователя.Мне, если честно, пока эта идея совсем не нравится. ;) Возможно, моё мнение изменится после того, как я попробую поиспользовать твой кверисет (я пока боюсь его, код непрост ;)), но что-то мне это совсем не нравится...
Я вот думаю, нельзя ли этим самым AutoOneToOneField'ом как-то присобачиваться к пользователю так, чтоб его "замечал" select_related и вытягивал? Я query.py раньше не читал, а щас глянул - тяжко будет отыскать, мне кажется, как это сделать. :( -
AutoOneToOnField там ни при чем, на самом деле, весь тот же код верен и для OneToOne и для ForeignKey. Основная проблема, почему это не сделано автоматически в select_related, в том, что зависимой записи (профиля) реально может не существовать. А значит, если завязаться на join с этой таблицей, то и сами юзеры, профилей у которых нет, не вернутся в результате запроса. Поэтому такую провязку вниз по отношениям можно делать только в том месте, где точно известно, что зависимые записи всегда создаются.
-
Да, но я хочу просто автоматом создавать профиль не при запросе, а при создании пользователя. И, соответственно, как-то так присобачицо, чтоб селект-релейтед вытаскивал профили. Или не селект релейтед, но чтоб лишние движения были минимальны.
Потому что ставить ссылку на профиль... Ну это не совсем правильно. :( -
"Неправильно" — это эмоциональная оценка :-). Технически смысл у этого решения есть. Хотя есть и минусы. Я однажды сделал так, завязавшись на профиль, но потом оказалось, что это неудобно потому что в большинстве случаев мне нужна была информация не из профиля, а из юзера, поэтому все обрастало цепочками типа album.user.core_user.username. А вот с Cicero у меня практически вся информация лежит в профиле, поэтому удобнее будет ссылаться на него.
Если у тебя первый случай — когда джанговский юзер тебе полезен, то мне кажется, что наследник queryset'а — вполне рабочее решение. -
"Неправильно" — это эмоциональная оценка :-).Да, но мне этого пока достаточно. ;)
Насчёт наследника кверисета - да, если моя идея не сработает, то заюзаю его. Я просто подумал, что если сделать как вот я придумал - то это получится решение всех текущих джанговых проблем с профилем, когда каждый сам себе должен что-то придумывать.
А так взял, подключил, написал нужные поля - и оно автоматом создаётся/удаляется, вытягивается из базы и вообще.
Хотя может быть это тоже зло?..
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.


