【问题标题】:TypeError: User() got an unexpected keyword argument 'is_staff'TypeError:用户()得到了一个意外的关键字参数“is_staff”
【发布时间】:2021-12-08 09:34:06
【问题描述】:

我是 django 的新手。我想创建一个登录、注册 API,所以我在 Internet 上找到了一个解决方案。但它不是用户我自己的用户模型,它使用django.contrib.auth.models import AbstractUser。我不需要AbtractUser 的某些字段,所以我给它=none。 这是我的模型代码:

from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.fields import JSONField
from django.contrib.auth.models import AbstractUser

# Create your models here.

# class User(models.Model):
#     name = models.CharField(null=False,blank=False, max_length=512)
#     username = models.CharField(null=False,blank=False, max_length=512, unique=True)
#     email = models.EmailField(null=False,blank=False, max_length=512, unique=True)
#     password = models.CharField(null=False,blank=False, max_length=512)
#     status = models.CharField(null=True,blank=True, max_length=512)
#     role = models.IntegerField(null=False, blank=False, default=1)
#     USERNAME_FIELD = 'username'
#     REQUIRED_FIELDS = []
#     def __str__(self):
#         return self.username

class User(AbstractUser):
    last_login = None
    is_staff = None
    is_superuser = None
    first_name = None
    last_name = None
    name = models.CharField(null=False,blank=False, max_length=512)
    username = models.CharField(null=False,blank=False, max_length=512, unique=True)
    email = models.EmailField(null=False,blank=False, max_length=512, unique=True)
    status = models.CharField(null=True,blank=True, max_length=512)
    role = models.IntegerField(null=False, blank=False, default=1)
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.username

class Category(models.Model):
    title = models.TextField(null=False, blank=False)
    description = models.TextField(null=False, blank=False)

 
class Question(models.Model):
    title = models.TextField(null=False, blank=False)
    description = models.TextField(null=False, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    choices = models.JSONField(null=False, blank=False)
    answer = models.TextField(null=False,blank=False)
    level = models.IntegerField(null=True, blank=True)

但我无法使用我的超级用户登录我的 Django 管理员。我创建了新的超级用户,但出现错误TypeError: User() got an unexpected keyword argument 'is_staff'

我创建超级用户的命令:python manage.py createsuperuser

我不明白为什么我的模型会影响我的应用超级用户。任何人都可以为我解释并给我一些解决方案。

这是我在序列化程序中的代码:

from django.contrib.postgres import fields
from rest_framework import serializers
from app.models import User, Question, Category

class RegistrationSerializer(serializers.ModelSerializer):

    email = serializers.EmailField(max_length=50, min_length=6)
    username = serializers.CharField(max_length=50, min_length=6)
    password = serializers.CharField(max_length=150, write_only=True)
    class Meta:
        model = User
        fields = ['id', 'name','email', 'username', 'password', 'role']
    def validate(self, args):
        email = args.get('email', None)
        username = args.get('username', None)
        if User.objects.filter(email=email).exists():
            raise serializers.ValidationError({'email': ('Email already exists')})
        if User.objects.filter(username=username).exists():
            raise serializers.ValidationError({'username': ('Username already exists')})

        return super().validate(args)
  

    # def create(self, validated_data):
    #     return User.objects.create_user(**validated_data)

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'name', 'username', 'email', 'role']

class CategorySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'title', 'description']

class QuestionSerializer(serializers.ModelSerializer):
    # category = CategorySerializer(read_only=False)
    class Meta:
        model = Question
        fields = ['id', 'description', 'category', 'choices', 'answer', 'level']

这是我在视图中的代码:

from django.db.models import query
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import generics
from rest_framework import viewsets
from rest_framework import serializers
from rest_framework import permissions
import uuid
from app.models import User, Category, Question
from app.serializers import UserSerializer, QuestionSerializer,  CategorySerializer, RegistrationSerializer

from django.shortcuts import get_object_or_404

# Create your views here.

class RegistrationAPIView(generics.GenericAPIView):

    serializer_class = RegistrationSerializer
    permission_classes = (permissions.IsAuthenticated,)
    def post(self, request):
        serializer = self.get_serializer(data = request.data)
        if(serializer.is_valid()):
            serializer.save()
            return Response({
                "RequestId": str(uuid.uuid4()),
                "Message": "User created successfully",
                
                "User": serializer.data}, status=status.HTTP_201_CREATED
                )
        
        return Response({"Errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

class ListUsersAPIView(APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self, request):
        listUser = User.objects.all()
        info = UserSerializer(listUser, many = True)
        return Response(data = info.data, status = status.HTTP_200_OK)

    # def post(self, request, format=None):
    #     serializer = UserSerializer(data=request.data)
    #     if serializer.is_valid():
    #         serializer.save()
    #         return Response(serializer.data, status=status.HTTP_201_CREATED)
    #     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class DetailUsersAPIView(APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self,request, id):
        try: 
            user = get_object_or_404(User, pk=id)
            data = UserSerializer(user).data
            return Response(data, status = status.HTTP_200_OK)
        except:
            return Response("Error",status = status.HTTP_404_NOT_FOUND)

    def patch(self, request, id):
        user = get_object_or_404(Users, pk=id)
        serializer = UserSerializer(user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class CategoryViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = CategorySerializer
    queryset = Category.objects.all()

class QuestionViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = QuestionSerializer
    queryset = Question.objects.all()

非常感谢。

【问题讨论】:

  • 您需要定义自己的UserManager来注册用户,而不使用is_staffis_superuserdocs.djangoproject.com/en/3.2/topics/auth/customizing/…
  • 如何定义我自己的UserManager。你的想法是我创建自己的用户模型?
  • @HuynmMinhTri:我认为您的User 模型确实是您用来创建和验证用户的用户模型。

标签: python django postgresql django-rest-framework


【解决方案1】:

您需要define your own UserManager [Django-doc] 注册用户,而不使用is_staffis_superuser 等。此管理器用于创建用户对象。由于您已将is_staffis_superuser 等字段设置为None,因此这些不再是模型字段。

因此,您应该实现自己的用户管理器,该管理器将不再尝试在用户模型中设置这些字段。所以这意味着它看起来像:

from django.contrib.auth.models import UserManager

class CustomUserManager(UserManager):
    def create_user(self, username, email=None, password=None, **extra_fields):
        return self._create_user(username, email, password, **extra_fields)

    def create_superuser(self, username, email=None, password=None, **extra_fields):
        return self._create_user(username, email, password, **extra_fields)

UserManager 不会将is_staff 和/或is_superuser 添加到使用的字段中。因此,您将 CutomUserManager 作为 objects 管理器分配给用户模型:

class User(AbstractUser):
    # ⋮
    objects = CustomUserModel()

【讨论】:

  • 对不起,我是 Django 的新手。我可以使用我的评论用户模型使用 JWT 创建登录、注册 API 吗?
  • @HuỳnhMinhTrí: 不,用户模型需要有一些额外的属性和方法来描述用户名字段,用户是否具有一定的权限等。你的自定义User 不适用模型?您是否将CustomuserManager 添加为User 模型的经理??
  • 我不知道如何创建自定义User 模型。我只是想找到一种方法来创建登录、注册 API,所以我研究了 GG。我想我需要一个详细的示例来了解有关此的更多信息。你能帮帮我吗?
  • 是 Django 管理员的超级用户与我创建的 User 模型共享数据库表吗?
  • @HuỳnhMinhTrí:您创建了自己的用户模型。由于该模型没有is_superuseris_admin,这意味着在为该模型创建记录时不应指定这些字段。
猜你喜欢
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多