Django UNIQUE constraint failed: accounts_user.username

Я реализую пользовательский Django с нуля. Почти все работает, но возникает проблема, когда я создаю нового пользователя из панели администратора Django следующим образом.

django.db.utils.IntegrityError: UNIQUE constraint failed: accounts_user.username

Почему эта ошибка возникает, даже если в моей модели username нет поля User? Я включил вспомогательные файлы здесь.

models.py

import uuid

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _

from .managers import CustomManager
from .utils import path_to_upload


# Create your models here.
class BaseModelMixin(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
    creation_date = models.DateTimeField(_("Created At"), auto_now=True)
    modification_date = models.DateTimeField(_("Modified At"),
                                             auto_now_add=True)

    class Meta:
        abstract = True


class User(AbstractUser, BaseModelMixin):

    display_name = models.CharField(_("Display Name"), max_length=200,
                                    blank=True, null=True)
    email = models.EmailField(_("Email Address"), unique=True,
                              blank=False, null=False)
    profile_pic = models.ImageField(_("Profile Picture"),
                                    upload_to=path_to_upload)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["display_name"]
    objects = CustomManager()

forms.py

from django import forms
from django.contrib.auth.password_validation import validate_password
from django.forms import TextInput, PasswordInput
from django.contrib.auth.forms import UserCreationForm
from django.utils.translation import gettext_lazy as _

from .models import User


class AdminUserRegistrationForm(UserCreationForm):

    password1 = forms.CharField(validators=[validate_password,],
                                widget=forms.PasswordInput(attrs={"placeholder": "Password"}))
    password2 = forms.CharField(validators=[validate_password, ],
                                widget=forms.PasswordInput(attrs={"placeholder": "Confirm Password"}))

    class Meta(UserCreationForm.Meta):
        model = User
        fields = ["display_name", "email", "profile_pic"]
        widgets = {}
        for field in fields:
            if field not in ("password", "profile_pic"):
                widgets[field] = TextInput(attrs={
                    "placeholder": field.replace("_", " ").title()
                })
        widgets["password"] = PasswordInput(render_value=True,
                                            attrs={'required': False})
        widgets["profile_pic"] = forms.FileInput()


class AdminUserUpdateForm(forms.ModelForm):

    password = forms.CharField(label=_("Password"), required=True,
                               validators=[validate_password],
                               widget=PasswordInput(render_value=True))

    class Meta:
        model = User
        fields = ["display_name", "profile_pic", "password"]
        widgets = {}
        for field in fields:
            if not field == "profile_pic":
                widgets[field] = TextInput(attrs={"placeholder": field.replace("_", " ").title()})

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

managers.py

from django.contrib.auth.models import BaseUserManager
from django.utils.translation import gettext_lazy as _


class CustomManager(BaseUserManager):

    def create_user(self, display_name, email, password, **extras):
        if not email:
            raise ValueError(_("Email is a mandatory field"))

        email = self.normalize_email(email)
        user = self.model(display_name=display_name, email=email, **extras)
        user.set_password(password)
        # user.save()

        return user

    def create_superuser(self, display_name, email, password, **extras):
        extras.setdefault("is_staff", True)
        extras.setdefault("is_active", True)
        extras.setdefault("is_superuser", True)

        if "is_superuser" not in extras:
            raise ValueError(_("'is_superuser' is mandatory for superuser"))
        if "is_staff" not in extras:
            raise ValueError(_("'is_staff' is mandatory for superuser"))

        return self.create_user(display_name, email, password, **extras)

admin.py

from django.contrib import admin

from . import models
from . import forms


# Register your models here.
class CustomUserAdmin(admin.ModelAdmin):

    # add_form = forms.AdminUserRegistrationForm
    form = forms.AdminUserRegistrationForm
    model = models.User
    list_display_links = None
    list_display = ("display_name", "email",)


admin.site.register(models.User, CustomUserAdmin)

Вы наследуете от AbstractBaseUser и у него есть поле username, чтобы полностью удалить его из вашей модели, вам нужно установить его как None в пользовательском классе пользователя:

class User(AbstractUser, BaseModelMixin):
    username = None
    ...

По умолчанию AbstractUser имеет поле username.

При выполнении USERNAME_FIELD = "email" username поле не будет удалено.
Это просто говорит Django использовать email как поле username вместо фактического поля username.

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

class User(AbstractUser, BaseModelMixin):
    # ...
    username = None
    # ...
Вернуться на верх