“这是必填栏。” DRF

时间:2019-07-22 21:06:21

标签: django authentication django-rest-framework jwt django-registration

开始处理DRF。我想用jwt token对用户进行身份验证。但是什么也没发生。我遇到了一个问题,即在创建用户时会得到: {“ user”:{“ email”:[“此字段为必填。”],“ Username”:[“此字段为必填。 “],”密码“:[”此字段为必填。“]}}。尽管所有字段均已填写。

模型

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)

1 个答案:

答案 0 :(得分:1)

我没有详细阅读本教程,但是由于某些原因,看来您发布到端点的有效负载的形状应该不同于DRF通常期望的形状。

  

不过,我们需要解决一件事。注意来自   “注册”请求在根目录具有所有用户信息   水平。我们的客户希望此信息在以下位置进行命名空间   “用户。”为此,我们需要创建一个自定义DRF渲染器。

所以不要发布此内容:

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

您必须将其全部嵌套在“用户”键下。

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