2016-06-13 105 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