2016-06-13 104 views
1

我正在構建一個新的Djnago應用程序。我正在使用django-rest-auth(http://django-rest-auth.readthedocs.io/en/latest/index.html)進行登錄和註冊。但是它有一些問題。Django休息驗證登錄和註冊失敗

確切的問題是:

  1. 對於登錄:登錄不成功,當我嘗試使用形式和原始數據通過選擇API登錄。它給出了"non_field_errors": ["User account is disabled."]錯誤。
  2. 用於註冊:當我填寫數據並進行註冊時,它會給我帶來錯誤,但是數據保存在數據庫中。

現在我已經做了不少的事情,我不知道我做錯了,我做的事情按以下順序

  1. 新鮮的Django其餘項目創建
  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('^[\[email protected]+-]+$'), _('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爲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 
    

自定義模式似乎工作,作爲其移民創建了所有提到的字段的表。我甚至可以在我的管理界面看到它。

這裏怎麼回事?

+0

轉到用戶帳戶表並檢查活動狀態? – Anurag

+0

我的主動地位是真實的。請參閱下面的對話。我也更新了一些問題,提及我也可以使用電子郵件登錄而不是用戶名 – Nitish

回答

1
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) 

您已經設置爲(IS_ACTIVE)作爲默認的 '假'。我認爲註冊時禁用用戶。這就是爲什麼在登錄時你會得到'禁用'的響應。

註冊或創建新帳戶時請使is_active = true。

+0

我更改了,並且註冊仍然不起作用:在API中,當我使用HTML表單時,它完全不成功,而使用RAW數據,它將錯誤顯示爲「詳細信息」:「方法\」GET \「不允許。」但用戶被添加到數據庫中。登錄使用RAW數據,但我認爲我的自定義用戶模型和註冊序列化程序之間有一些衝突(我注意到有全名和短名稱,而不是first_name和last_name)我將其稱爲http://blog.mathandpencil.com/在我的自定義用戶模型中替換-django-custom-user-models-in-an-existing-application/ – Nitish

+0

我的自定義用戶模型中引用的鏈接是:https://www.lasolution.be/blog/creating- custom-user-model-django-16-part-1.html – Nitish

1

我沒有升級Django版本,並在註冊和登錄開始工作時重新安裝了django-rest-auth和django-allauth,但不完全正確。

通過API使用它的原始數據,只有當不使用時HTML形式是可能的,請截圖:

enter image description here

註銷仍然是斷開的。

enter image description here

對於這兩個問題的任何進一步的答案? 註銷啓用HTML

+1

這也是通過將Django-rest-framework升級到最新版本來解決的 – Nitish