1

新しい Djnago アプリケーションを構築しています。ログインと登録にdjango-rest-auth ( http://django-rest-auth.readthedocs.io/en/latest/index.html ) を使用しています。ただし、それにはいくつかの問題があります。

正確な問題は次のとおりです。

  1. ログインの場合: フォームと生データの両方のオプションを使用して API 経由でログインしようとすると、ログインに失敗します。エラーが発生し"non_field_errors": ["User account is disabled."]ます。
  2. 登録の場合: データを入力して登録するとエラーが発生しますが、データはデータベースに保存されます。

今、私はかなりの数のことをしましたが、何が間違っていたのかわかりません。次の順序で物事を行いました

  1. 新しく作成された Django rest プロジェクト
  2. カスタム ユーザー モデルを持つ myauth というアプリを作成しました。次のようになります。

    class UserManager(BaseUserManager):
    
    def _create_user(self, username, email, password, is_staff, is_superuser, **extra_fields):
    now = timezone.now()
    if not username:
     raise ValueError(_('The given username must be set'))
    email = self.normalize_email(email)
    user = self.model(username=username, email=email,
         is_staff=is_staff, is_active=False,
         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, username, email=None, password=None, **extra_fields):
    return self._create_user(username, email, password, False, False,
             **extra_fields)
    
    def create_superuser(self, username, email, password, **extra_fields):
    user=self._create_user(username, email, password, True, True,
             **extra_fields)
    user.is_active=True
    user.save(using=self._db)
    return user
    
    
    class User(AbstractBaseUser, PermissionsMixin):
       username = models.CharField(_('username'), max_length=30, unique=True,
       help_text=_('Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters'),
       validators=[
       validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), _('invalid'))
       ])
       first_name = models.CharField(_('first name'), max_length=30, blank=True, null=True)
       last_name = models.CharField(_('last name'), max_length=30, blank=True, null=True)
       email = models.EmailField(_('email address'), max_length=255, unique=True)
       is_staff = models.BooleanField(_('staff status'), default=False,
       help_text=_('Designates whether the user can log into this admin site.'))
       is_active = models.BooleanField(_('active'), default=False,
       help_text=_('Designates whether this user should be treated as active. Unselect this instead of deleting accounts.'))
       date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
       receive_newsletter = models.BooleanField(_('receive newsletter'), default=False)
       birth_date = models.DateField(auto_now=False, null=True)
       address = models.TextField(max_length=500, null=True)
       phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
       phone_number = models.CharField(validators=[phone_regex], blank=True, max_length=20) # validators should be a list
    
    
      USERNAME_FIELD = 'email'
      REQUIRED_FIELDS = ['username',]
    
      objects = UserManager()
    
      class Meta:
       verbose_name = _('user')
       verbose_name_plural = _('users')
    
      def get_full_name(self):
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()
    
     def get_short_name(self):
        return self.first_name
    
    def email_user(self, subject, message, from_email=None):
        send_mail(subject, message, from_email, [self.email]) 
    
  3. settings.py as に追加しAUTH_USER_MODEL = 'myauth.User'、admin.py にも登録しました。移行により、上記の列を持つすべてのテーブルが作成されました。

  4. first_name と last_name をユーザー名と電子メールとパスワードと共に登録できるように登録を変更したいと思いました。また、ユーザー名の代わりに電子メールを使用してログインできるようにしました。そのため、ユーザー モデルと settings.py で衝突するコードが存在する可能性があります。そのために、serializers.py に次のコードを追加しました。

     from myauth.models import User
    
     from allauth.account import app_settings as allauth_settings
     from allauth.utils import email_address_exists
     from allauth.account.adapter import get_adapter
     from allauth.account.utils import setup_user_email
    
     #Custom registration to store first and last name along with email and password 
     class RegisterSerializer(serializers.Serializer):
     email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
     first_name = serializers.CharField(required=True, write_only=True)
     last_name = serializers.CharField(required=True, write_only=True)
     password1 = serializers.CharField(required=True, write_only=True)
     password2 = serializers.CharField(required=True, write_only=True)
    
     def validate_email(self, email):
         email = get_adapter().clean_email(email)
         if allauth_settings.UNIQUE_EMAIL:
           if email and email_address_exists(email):
            raise serializers.ValidationError(
                _("A user is already registered with this e-mail address."))
     return email
    
     def validate_password1(self, password):
       return get_adapter().clean_password(password)
    
     def validate(self, data):
       if data['password1'] != data['password2']:
        raise serializers.ValidationError(
            _("The two password fields didn't match."))
      return data
    
     def get_cleaned_data(self):
       return {
        'first_name': self.validated_data.get('first_name', ''),
        'last_name': self.validated_data.get('last_name', ''),
        'password1': self.validated_data.get('password1', ''),
        'email': self.validated_data.get('email', ''),
      }
    
     def save(self, request):
       adapter = get_adapter()
       user = adapter.new_user(request)
       self.cleaned_data = self.get_cleaned_data()
       adapter.save_user(request, user, self)
       setup_user_email(request, user, [])
       user.save()
       return user
    
  5. 私のsettings.pyは次のようになります:

    INSTALLED_APPS = (
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'rest_framework',
     'rest_framework.authtoken',
     'rest_auth',
     'allauth',
     'allauth.account',
     'rest_auth.registration',
     'myauth',
     'swarms_app'
    )
    
    AUTH_USER_MODEL = 'myauth.User'
    
    MIDDLEWARE_CLASSES = (
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
     )
    
     ROOT_URLCONF = 'urls'
    
    TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
          },
        },
       ]
    
       WSGI_APPLICATION = 'config.wsgi.application' 
    
    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  
        'NAME': 'new_swarms',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': 'localhost',   # Or an IP Address that your DB is hosted on
        'PORT': '3306',
    }
    }
    
    
    STATIC_URL = '/static/'
    
    ##############################################################
    ## All the customization as taken from original swarms code ## 
    ##############################################################
    
    
    #This is added to use custon registration serializer which stores first and last name along with email and password
    REST_AUTH_REGISTER_SERIALIZERS = {
        'REGISTER_SERIALIZER': 'myauth.serializers.RegisterSerializer',
    } 
    
    REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
    }
    
    #Following is added to enable registration with email instead of username
    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",
    )
    
    #This is required otherwise it asks for email server
    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
    
    ACCOUNT_AUTHENTICATION_METHOD = 'email'
    ACCOUNT_EMAIL_REQUIRED = True   
    ACCOUNT_USERNAME_REQUIRED = False
    

私が作成したカスタムモデルは、移行時に上記のすべてのフィールドを含むテーブルを作成したため、機能しているようです。管理画面でも見ることができます。

ここで何がうまくいかないのですか?

4

2 に答える 2

1

登録とログインが機能し始めたときに、Djangoのバージョンをアップグレードし、django-rest-authとdjango-allauthを再インストールしましたが、完全には正しくありませんでした。

API を介して、生データを使用している場合にのみ可能であり、HTML フォームを使用している場合は可能ではありません。スクリーンショットを参照してください:

ここに画像の説明を入力

ログアウトはまだ壊れています。

ここに画像の説明を入力

これらの両方の問題に対するさらなる答えはありますか? ログアウトて HTML で有効にしますか?

于 2016-06-13T09:13:08.317 に答える