Python - /accounts/signup/ に FieldDoesNotExist、ユーザーには ,username という名前のフィールドがありません、

okwaves2024-01-25  6

私は 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'

この記事を試しましたが、役に立たないようです。 私の AbstractBaseUser では、ユーザー名ではなく電子メールを使用することにしました。どうすればいいですか?いくつかのオプションが不足しているのでしょうか? 私は Python 3.8.5 と Django 3.1.1 を使用しています

モデル.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 ドキュメントで指定されているように、設定でカスタム ユーザー作成フォームを指定していないことがわかりました。

次の行を設定、アプリに追加しました。正常に動作し始めました。

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

ここで、users はアプリ名、forms は Forms.py、UserCreationForm はカスタム ユーザー作成フォームの名前です。

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。