Использование электронной почты в качестве поля имени пользователя в пользовательской модели пользовательской модели Django 1.5 в FieldError
Я хочу использовать поле электронной почты в качестве поля имени пользователя для моей пользовательской модели.
У меня есть следующая пользовательская модель подкласса модели Django AbstractUser:
class CustomUser(AbstractUser):
....
email = models.EmailField(max_length=255, unique=True)
USERNAME_FIELD = 'email'
Но когда я запустил
python manage.py sql myapp
Я получаю следующую ошибку:
FieldError: локальное поле "email" в классах "CustomUser" сталкивается с полем аналогичного имени из базового класса "AbstractUser"
Причина, по которой я включаю свое собственное поле электронной почты, в первую очередь - добавить к ней параметр unique=True
. в противном случае я получаю:
myapp.customuser: USERNAME_FIELD должен быть уникальным. Добавить уникальный = Верно для параметров поля.
Теперь, в связи с этим:
https://docs.djangoproject.com/en/1.5/topics/db/models/#field-name-hiding-is-not-permitted
Как может достичь этого? (другой, затем называя поле "user_email" или что-то в этом роде)
Ответы
Ответ 1
Ян, большое спасибо за умный ответ:)
Однако я уже "исправил" меня решение.
Так как AbstractUser
также имеет поле username
, которое для меня совершенно ненужно
Я решил создать свой "собственный" AbstractUser
.
Подклассификация AbstractBaseUser
и PermissionsMixin
Я сохраняю большинство встроенных методов модели User без добавления кода.
Я также воспользовался этой возможностью, чтобы создать пользовательский Manager
, чтобы полностью исключить использование в поле username
:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
....
email = models.EmailField(max_length=255, unique=True)
first_name = ...
last_name = ...
is_active = ...
is_staff = ...
....
objects = CustomUserManager()
USERNAME_FIELD = 'email'
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
.....
def create_superuser(self, email, password, **extra_fields):
.....
Это решение приводит к повторению некоторого встроенного кода Django (в основном, поля модели, которые уже существуют в AbstractUser
, таких как "first_name", "last_name" и т.д.), но также и в более чистой таблице объектов пользователя и базы данных.
Настоящим позором является то, что гибкость, введенная в 1.5 с помощью USERNAME_FIELD
, не может использоваться для актуальной создания гибкой модели пользователя при всех существующих ограничениях.
EDIT: в официальных документах есть подробный рабочий пример: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example
Ответ 2
Если ваша реальная цель - это уникальные значения "электронной почты" и игнорирование значений "имя пользователя", вы можете:
- Заполните "имя пользователя", например.
sha256(user.email).hexdigest()[:30]
-
Добавьте уникальность таким образом:
class User(AbstractUser):
class Meta:
unique_together = ('email', )
Это приводит к:
CREATE TABLE "myapp_user" (
...
"email" varchar(75) NOT NULL,
UNIQUE ("email")
)
работает так, как ожидалось, и довольно просто.
Ответ 3
Вы можете изменить свой CustomUser
, чтобы изменить атрибут поля email
на unique=True
.
Добавьте это в конец своего пользовательского класса, например:
class CustomUser(AbstractUser):
...
USERNAME_FIELD = 'email'
...
CustomUser._meta.get_field_by_name('email')[0]._unique=True
Обратите внимание, что мы меняем _unique
, а не unique
, потому что последний является простым @property
.
Это хак, и я хотел бы услышать любые "официальные" ответы, чтобы решить эту проблему.
Ответ 4
Используйте пример с официального сайта:
https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example
Вот пример пользовательского пользовательского приложения, совместимого с администратором. Эта модель пользователя использует адрес электронной почты в качестве имени пользователя и имеет необходимую дату рождения; он не обеспечивает проверку разрешений за пределами простого флага администратора в учетной записи пользователя. Эта модель будет совместима со всеми встроенными формами и представлениями auth, за исключением форм создания пользователя. Этот пример иллюстрирует, как большая часть компонентов работает вместе, но не предназначена для копирования непосредственно в проекты для использования в производстве.