FieldDoesNotExist 在 /accounts/signup/,用户没有名为 'username' 的字段

FieldDoesNotExist at /accounts/signup/, User has no field named 'username'

我正在使用 django allauth,并且我正在使用 AbstractBaseUser,但是每当我点击注册时,它都会显示

跟踪:

C:\Users\user1\.virtualenvs\allauthtest-RfdvfJzX\lib\site-packages\django\db\models\options.py, line 577, in get_field

  raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))

     
FieldDoesNotExist at /accounts/signup/

User has no field named 'username'

我试过this article,但似乎对我没有帮助。 在我的 AbstractBaseUser 中,我决定使用电子邮件,而不是用户名。我应该怎么办?我错过了一些选择吗? 我正在使用 Python 3.8.5 和 Django 3.1.1

models.py

class UserManager(BaseUserManager):
    """
    Custom User Model manager.
    It inherits from BaseUserManager, and has 3 functions, 
    create_user(), create_staffuser(), and create_superuser()
    It requires email field.
    """
    def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
        if not email:
            raise ValueError('Users must have an email address')
        now = timezone.now()
        email = self.normalize_email(email)
        user = self.model(
            email=email,            
            is_staff=is_staff, 
            is_active=True,
            is_superuser=is_superuser, 
            last_login=now,
            date_joined=now, 
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_user(self, email, password, **extra_fields):
        """
        Creates and saves a User with the given email and password.
        """
        return self._create_user(email, password, False, False, **extra_fields)

    def create_staffuser(self, email, password, **extra_fields):
        """
        Creates and saves a staff user with the given email and password.
        """
        user=self._create_user(email, password, True, False, **extra_fields)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password, **extra_fields):
        """
        Creates and saves a superuser with the given email and password.
        """
        user=self._create_user(email, password, True, True, **extra_fields)
        user.save(using=self._db)
        return user


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    first_name = models.CharField(max_length=70, null=True, blank=True)        
    last_name = models.CharField(max_length=70, null=True, blank=True)  
    display_name = models.CharField(('display name'), max_length=70, blank=True, null=True, unique=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False) # a admin user; non super-user
    is_superuser = models.BooleanField(default=False) # a superuser
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    # notice the absence of a "Password field", that is built in.        

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name'] # Email & Password are required by default.
    
    objects = UserManager()
    
    class Meta:
        verbose_name = ('user')
        verbose_name_plural = ('users')
        #db_table = 'auth_user'
        abstract = False
    
    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)
    
    @property
    def name(self):
        if self.first_name:
            return self.first_name
        elif self.display_name:
            return self.display_name
        return 'You'
    
    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    def email_user(self, subject, message, from_email=None):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email])

    def __str__(self):              
        return self.email
    
    def natural_key(self):
        return (self.email,)

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

然后我的settings.py

from decouple import config, Csv
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', cast=bool)

ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())


# Application definition

INSTALLED_APPS = [
    # Default
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    
    # 3rd party    
    'crispy_forms',
    
    'allauth', 
    'allauth.account', 
    'allauth.socialaccount', 
    #'allauth.socialaccount.providers.google', 
    #'allauth.socialaccount.providers.facebook',
    
    
    # local
    'pages',
    'users',
    
    
]



DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': config('DB_NAME'),
        'USER': config('DB_USER'),
        'PASSWORD': config('DB_PASSWORD'),
        'HOST': config('DB_HOST'),
        'PORT': '',
    }
}



AUTH_USER_MODEL = 'users.User'
AUTHENTICATION_BACKENDS = (
    # Needed to login by username in Django admin, regardless of `allauth`
    "django.contrib.auth.backends.ModelBackend",

    # `allauth` specific authentication methods, such as login by e-mail
    "allauth.account.auth_backends.AuthenticationBackend",
)


SITE_ID = 1

ACCOUNT_EMAIL_VERIFICATION = 'mandatory'

LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

# Django All Auth settings
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 7
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = LOGOUT_REDIRECT_URL
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL  = None
ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5
ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 3600
ACCOUNT_USERNAME_BLACKLIST = ['admin', 'superuser', 'user']


#SOCIALACCOUNT_EMAIL_REQUIRED = True
######3# SOCIALACCOUNT_ADAPTER = 'users.adapter.DisableSocialLoginAdapter'
#SOCIALACCOUNT_EMAIL_VERIFICATION = 'mandatory'

我发现我没有在我的设置中指定我的自定义用户创建表单,如 django-allauth docs

中指定的

我刚刚将以下行添加到我的设置中,应用开始正常运行。

ACCOUNT_FORMS = {'signup': 'users.forms.UserCreationForm'}

其中 users 是我的应用名称,forms 是我的 forms.pyUserCreationForm 是我的自定义用户创建表单的名称。