无法在Django

时间:2015-11-10 22:56:04

标签: django authentication django-models django-templates django-views

我创建了一个Custom User model in Django,您在下面看到我的models.py

from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from uuidfield import UUIDField

class User(AbstractUser, Mixin):
    objects = HiddenUserManager()
    USERNAME_FIELD = 'username'
    # REQUIRED_FIELDS = ['email', 'password']
    api_token = UUIDField(auto=True)
    token_created_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('email', )  # must have unique email!
        app_label = 'portal'

    def api_token_reset(self):
        self.api_token = UUIDField(auto=True)

我还更改了我的settings.py文件并添加了这一行:

AUTH_USER_MODEL = 'portal.User' portal是我的应用程序的名称。

我使用superusers创建了两个portal.user model,如下图所示: enter image description here

问题是当我在索引登录页面中输入username and password时,它无法验证我。创建模型后,我执行了所有migrations。为什么登录页面无法验证我?

如果我发表评论customer user model并删除此行AUTH_USER_MODEL = 'portal.User',那么我的登录页面就可以对我进行身份验证。知道我哪里错了吗?

我的登录视图如下所示:

from django.contrib.auth.views import login
from django.http import HttpResponseRedirect

def login(request, **kwargs):
    return login(request, **kwargs)

有人可以帮我吗?

更新:Mixin类

class RequireStaffMixinView(RequireAuthMixinView):
    # Override 1) ensure staff
    # @method_decorator(staff_user_required)
    def dispatch(self, *args, **kwargs):
        if not self.request.user.is_staff:
            raise PermissionDenied
        return super(RequireAuthMixinView, self).dispatch(*args, **kwargs

2 个答案:

答案 0 :(得分:1)

要创建自定义用户模型,请按照django docs的建议扩展AbstractBaseUser模型,并将自定义字段添加到其中。

另请注意,由于Django对可交换模型的动态依赖性功能的限制,您必须确保在其应用程序的第一次迁移(通常称为0001_initial)中创建AUTH_USER_MODEL引用的模型;否则,您将遇到依赖性问题。

models.py

import uuid

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models


class CustomUserManager(BaseUserManager):
    def create_user(self, email, password, **kwargs):
        if not email or not password:
            raise ValueError('User must have a username and password')

        user = self.model(
            email=CustomUserManager.normalize_email(email),
            **kwargs
        )

        user.set_password(password)
        user.save()

        return user

    def create_superuser(self, email, password, **kwargs):
        user = self.create_user(email, password, **kwargs)

        user.is_admin = True
        user.is_staff = True
        user.save()

        return user


class User(AbstractBaseUser):
    first_name = models.CharField(max_length=255, null=False)
    last_name = models.CharField(max_length=255, null=False)
    email = models.EmailField(null=False, unique=True)
    is_active = models.BooleanField(default=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    is_staff = models.BooleanField(default=False)

    # Add custom fields here
    api_token = models.UUIDField(default=uuid.uuid4, editable=False)
    token_created_date = models.DateTimeField(auto_now_add=True)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def get_full_name(self):
        return self.first_name + " " + self.last_name

    def get_short_name(self):
        return self.first_name

    def has_perm(self, perm, obj=None):
        return self.is_staff

    def has_module_perms(self, app_label):
        return self.is_staff

    def api_token_reset(self):
        self.api_token = models.UUIDField(default=uuid.uuid4, editable=False)

    class Meta:
        ordering = ('created_on',)
        db_table = 'users'

    def __unicode__(self):
        return self.get_full_name()

并将以下代码添加到settings.py中。注意 - tester是我的应用程序的名称

AUTH_USER_MODEL = 'tester.User'

现在运行以下命令 -

python manage.py makemigrations
python manage.py migrate

现在您应该能够毫无问题地登录django管理员。

如果要创建自定义登录页面,请在视图中检查用户是否为管理员 -

views.py

from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponseRedirect
from django.views.generic import FormView


class LoginView(FormView):
    form_class = AuthenticationForm
    template_name = 'login.html'

    def form_valid(self, form):
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        user = authenticate(username=username, password=password)

        # Check here if the user is an admin
        if user is not None and user.is_active and user.is_staff:
            login(self.request, user)
            return HttpResponseRedirect(self.success_url)
        else:
            return self.form_invalid(form)

的login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<form method="post">
    {%  csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>
</body>
</html>

urls.py

from django.conf.urls import url

from .views import LoginView

urlpatterns = [
    url(r'^login/$', LoginView.as_view(), name='login'),
]

答案 1 :(得分:-1)

不知道如何,但我添加了 is_active ,is_admin, is_staff ,is_superuser as true 是超级用户创建功能在 create user 中将 is_active 更改为 true 并在 settings.py 中添加了上述指定的后端,它开始工作你只需要创建在所有这些更改之后,新的超级用户和新的数据库具有新的迁移。它应该工作...

创建超级用户函数:

 def create_superuser(self,email, user_name, address, password, **other_fields):
        user = self.creat_user(email,user_name,address ,password=password,**other_fields)
        user.is_admin = True
        user.is_active = True
        user.is_staff = True
        user.is_superuser = True
        user.save()

        return user

创建用户函数

class NewUser(AbstractBaseUser,PermissionsMixin):
    alphanumeric = RegexValidator(r'^[0-9a-zA-Z]*$', message='Only alphanumeric characters are allowed.') 
    email = models.EmailField(_('Enter Email'),unique=True)
    user_name = models.CharField(max_length=20, unique=True, validators=[alphanumeric])
    address= models.TextField(_(
        'enter Address'),max_length=500,blank=True)

    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    objects =CustomeAccountManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['user_name','address']

    def __str__(self):
        return self.email