Расширение объекта User в Django: Наследование модели пользователя или использование UserProfile?

Чтобы расширить объект User с помощью настраиваемых полей, в документах Django рекомендуется использовать UserProfiles. Однако, согласно этим, ответьте на вопрос об этом через год или около того:

расширение django.contrib.auth.models.User также работает лучше сейчас - с момента рефакторинга кода наследования Django в API моделей.

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

Поэтому мне было интересно, существует ли какой-либо консенсус по этому вопросу или причины использовать тот или иной. Или даже то, что в настоящее время думает команда Django?

Ответы

Ответ 1

Я проголосую за использование UserProfiles.

Я использую несколько приложений для вечеринок. И внешний ключ для пользователя всегда будет указывать на auth.models.User.

Пример:

class Article(models.Model):
    user = models.ForeignKey('auth.User') # instead of your CustomUser
    text = ....

И ваша пользовательская модель пользователя:

class CustomUser(User):
    timezone = models.CharField(max_length=50, default='Europe/London')

    # Use UserManager to get the create_user method, etc.
    objects = UserManager()

Что произойдет, если вы получите доступ к полю пользователя через экземпляр статьи? Это вызовет исключение:

u = a_article.user
u.timezone

AttributeError: 'User' object has no attribute 'timezone'

Возможно, это не проблема для вас, и вы не должны избегать дополнительного запроса БД. Но я бы использовал путь get_profile.

ОБНОВЛЕНИЕ май 2013 г.

С Django 1.5 вы можете extend модель пользователя по умолчанию, или заменить с полностью настроенной моделью.

ОБНОВЛЕНИЕ Ноябрь 2016

Вышеупомянутое решение устарело, см. комментарий от wim

Ответ 2

Вот что Джеймс Беннетт говорит в этой записи в блоге о Наследование модели:

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

Итак, я считаю, что лучший способ - использовать внешнее приложение, например, некоторые компоненты Pinax, или django-profiles приложение (первоначально из того же Джеймса Беннетта).