Django - 无法使用自定义用户模型

时间:2018-01-10 01:10:18

标签: python django django-models django-forms django-views

以前,我一直在使用默认的Django用户模型,并且在我们的views.py中使用此代码注册时没有任何问题,已经将用户添加到特定用户组:

user.save() user.groups.add(Group.objects.get(name='customers'))

但是,我现在已更改为自定义用户模型,因此我可以删除用户名'我的注册表单中的字段,现在此代码不再有效。当新用户尝试注册时,将抛出此错误消息:

'用户'对象没有属性' groups'

我已搜索但无法找到此问题的答案。我非常擅长使用Django处理后端,所以请在你的答案中描述一下(比如我需要把你建议的代码放在models.py/views.py/forms.py等)。任何帮助将不胜感激!

我的models.py:

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

class UserManager(BaseUserManager):
    def create_user(self, email, first_name, last_name, password=None, is_staff=False, is_admin=False):
        if not email:
            raise ValueError("Users must enter an email")

        if not password:
            raise ValueError("Users must enter a password")

        if not first_name:
            raise ValueError("Users must enter their first name")

        if not last_name:
            raise ValueError("Users must enter their last name")

        user_obj = self.model(
            email = self.normalize_email(email),
            first_name = first_name,
            last_name = last_name,
        )
        user_obj.set_password(password) #set and change password?
        user_obj.admin = is_admin
        user_obj.staff = is_staff
        user_obj.save(using=self._db)
        return user_obj

    def create_superuser(self, email, first_name, last_name, password=None):
        user = self.create_user(
            email,
            first_name,
            last_name,
            password=password,
            is_staff=True,
            is_admin=True
        )
        return user

class User(AbstractBaseUser):
    first_name = models.CharField(max_length=255, blank=True, null=True)
    last_name = models.CharField(max_length=255, blank=True, null=True)
    email = models.EmailField(max_length=255, unique=True)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    # active = models.BooleanField(default=True) #can login
    staff = models.BooleanField(default=False) #staff not superuser
    admin = models.BooleanField(default=False) #superuser

    USERNAME_FIELD = 'email'

    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = UserManager()

    def __str__(self):
        return self.email

    def get_first_name(self):
        return self.email

    def get_last_name(self):
        return self.email


    def get_short_name(self):
        return self.email

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

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_admin(self):
        return self.admin

formy.py

from django import forms
from django.contrib.auth import (
    authenticate,
    get_user_model,
    login,
    logout,
    )
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.models import User, Group


User = get_user_model()

class UserAdminCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email', 'first_name', 'last_name')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserAdminCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

views.py

from __future__ import unicode_literals
from barbers.forms import BarberProfileForm
from barbers.models import BarberProfile
from django.contrib.auth.models import User, Group
from django.contrib.auth import (
    authenticate,
    get_user_model,
    login,
    logout,
    )
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render, get_object_or_404
from .forms import BarberRegisterForm, UserLoginForm, UserRegisterForm, UserAdminCreationForm

def register_view(request):

    print(request.user.is_authenticated())

    register_title = "Register"
    register_form = UserAdminCreationForm(request.POST or None)
    if register_form.is_valid():
        user = register_form.save(commit=False)
        password = register_form.cleaned_data.get('password')
        user.set_password(password)
        user.save()
        user.groups.add(Group.objects.get(name='customers'))
        new_user = authenticate(username=user.username, password=password)
        login(request, new_user)
        if next:
            return redirect(next)
        return redirect("/my-barbers/{0}".format(request.user.id), user=request.user)

    context = {
        "register_form": register_form,
        "register_title": register_title,
    }

    return render (request, "login.html", context)

1 个答案:

答案 0 :(得分:1)

您的自定义作业用户模型是什么?

也许你继承了AbstractUserAbstractBaseUser

但是当您需要使用groups时,您必须继承PermissionsMixin

    from django.contrib.auth.models import PermissionMixin

您可以登入django github code here

这是代码的一部分

class PermissionsMixin(models.Model):
    """
    Add the fields and methods necessary to support the Group and Permission
    models using the ModelBackend.
    """
    is_superuser = models.BooleanField(
        _('superuser status'),
        default=False,
        help_text=_(
            'Designates that this user has all permissions without '
            'explicitly assigning them.'
        ),
    )
    groups = models.ManyToManyField(
        Group,
        verbose_name=_('groups'),
        blank=True,
        help_text=_(
            'The groups this user belongs to. A user will get all permissions '
            'granted to each of their groups.'
        ),
        related_name="user_set",
        related_query_name="user",
    )
希望解决得好!

添加

这是我用户模型的一部分。您应该继承BaseUserPermissionsMixin。然后,您可以使用groups中的PermissionsMixin

class JobUser(AbstractBaseUser, PermissionsMixin, TimeStampedModel):
    email = models.EmailField(
        verbose_name="Email",
        max_length=255,
        unique=True,
        db_index=True,
    )
    user_type = models.PositiveIntegerField(
        verbose_name="User type",
        # 0 - staff
        # 1 - employer
        # 2 - employee
        choices=CHOICES.USER_CHOICES,
        default=2,
    )
    ...
  

所以你的用户模型就像......

class User(AbstractBaseUser, PermissionsMixin):
    first_name = models.CharField(max_length=255, blank=True, null=True)
    last_name = models.CharField(max_length=255, blank=True, null=True)
    email = models.EmailField(max_length=255, unique=True)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    # active = models.BooleanField(default=True) #can login
    staff = models.BooleanField(default=False) #staff not superuser
    admin = models.BooleanField(default=False) #superuser
    ...

另外,请不要忘记在代码顶部导入PermissionMixin

希望解决好!