Связывание внешнего ключа с auth.Пользовательская модель

#django #django-models #models

#django #django-модели #Модели

Вопрос:

Я пытаюсь связать Account модель со стандартной моделью django auth.User .

Я вижу, как это происходит, чтобы иметь ForeignKey on User , указывающий на Account , поэтому я могу использовать что-то вроде account.users .

Вот так

 class User(User):
    account = ForeignKey(Account, related_name='users')
    ...
  

Однако, как мы все знаем, рекомендуемый способ добавления информации в User модель — через UserProfile .

Вот так

 class UserProfile(models.Model):
    account = ForeignKey(Account, related_name='profiles')
    user = ForeignKey(User)
    ...
  

это означает, что если я хочу получить список всех Users в Account учетной записи, мне нужно сделать что-то вроде,

 users = [p.user for p in account.profiles]
  

Хотя это всего лишь одна строка, я предполагаю, что каждая p.user генерирует дополнительный доступ к базе данных, что кажется крайне неэффективным по сравнению с тем, если бы User модель была доступна напрямую через Account модель.

Есть ли более эффективный способ сделать это? Или я здесь упускаю что-то очевидное?

Комментарии:

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

Ответ №1:

Вы можете избежать дополнительных поисков в базе данных для каждого профиля, используя select_related .

 profiles = account.select_related().profiles
  

также будет включать все пользовательские запросы в рамках единственного запроса.

Вот документация:http://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related

Комментарии:

1. К сожалению, select_related() кажется, что работает только в обратном направлении для OneToOneField s, а не ForeignKey для s. Итак, хотя я мог бы использовать select_related() при запросе UserProfile s для извлечения Account s (поскольку UserProfile определяет ForeignKey to Account ), я не мог сделать это из Account

Ответ №2:

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

 users = User.objects.filter(userprofile__account=account)
  

Комментарии:

1. Да, это действительно сработало бы, хотя и немного окольным путем и требует небольшого переключения контекста. Ну, во всяком случае, для меня. (И для этого потребовалось бы дополнительное объединение, но я могу с этим смириться =)

2. Для этого потребуется дополнительное объединение? Это привело бы к созданию одного файла JOIN — User JOIN UserProfile. В любом случае я рад, что вы нашли этот ответ полезным.

3. Я полагаю, что одно «дополнительное» объединение по сравнению с тем, если бы account поле хранилось непосредственно в User , но у меня это работает, спасибо =)