"This field is required." DRF

"This field is required." DRF

开始处理DRF。我想使用 jwt token 对用户进行身份验证。但是没有任何反应。我遇到了创建用户时遇到的问题:{"user": {"email": ["This field is required."], "Username": [ "This field is required."], "Password": ["This field is required."]}}. 尽管所有字段都已填写。

型号

class UserManager(BaseUserManager):
    def create_user(self, username, email, password=None):
        if username is None:
            raise TypeError('Users must have a username.')
​
        if email is None:
            raise TypeError('Users must have an email address.')
​
        user = self.model(username=username, email=self.normalize_email(email))
        user.set_password(password)
        user.save()

        return user
​
​
class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(db_index=True, max_length=255, unique=True)
    email = models.EmailField(db_index=True, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    bio = RichTextUploadingField(_('bio'), blank=True)
    city = models.CharField(_('city'), max_length=100, blank=True)
​
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']
​
    objects = UserManager()
​
    @property
    def token(self):
        return self._generate_jwt_token()
​
    def _generate_jwt_token(self):
        dt = datetime.now() + timedelta(days=60)
​
        token = jwt.encode({
            'id': self.pk,
            'exp': int(dt.strftime('%s'))
        }, settings.SECRET_KEY, algorithm='HS256')

        return token.decode('utf-8')

序列化程序

class RegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(
        max_length=128,
        min_length=8,
        write_only=True
    )
    token = serializers.CharField(max_length=255, read_only=True)
​
    class Meta:
        model = User
        fields = ['email', 'username', 'password', 'token']

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

查看

class RegistrationAPIView(APIView):
    permission_classes = (AllowAny,)
    renderer_classes = (UserJSONRenderer,)
    serializer_class = RegistrationSerializer
​
    def post(self, request):
        print('request.data: \t\t', request.data)         #<QueryDict: {'{\n    "email": "sasasas@sasas.ssas",\n    "username": "sasasasas",\n    "password": "12345678"\n}': ['']}>
        print('request.data.get("user", {}): \t', request.data.get('user', {}))            #{}
        user = request.data.get('user', {})
​
        serializer = self.serializer_class(data=user)
        serializer.is_valid(raise_exception=True)     #Error
        serializer.save()
​
        return Response(serializer.data, status=status.HTTP_201_CREATED)

我没有详细阅读教程,但似乎出于某种原因,您 post 到端点的有效载荷应该与 DRF 通常期望的形状不同。

There is one thing we need to fix though. Notice how the response from the "Register" request has all of the user's information at the root level. Our client expects this information to be namespaced under "user." To do that, we'll need to create a custom DRF renderer.

所以不要 post 这样做:

{ 
  "email": "user@example.com",
  "username": "user",
  "password": "hunter2"
}

您必须将其全部嵌套在 "user" 键下。

{
  "user": { 
    "email": "user@example.com",
    "username": "user",
    "password": "hunter2"
  }
}