“这是必填栏。” DRF

Posted

技术标签:

【中文标题】“这是必填栏。” DRF【英文标题】:"This field is required." DRF 【发布时间】:2019-11-30 21:12:39 【问题描述】:

开始处理DRF。我想用jwt token 对用户进行身份验证。但什么也没有发生。我遇到的问题是,在创建用户时,我得到: "user": "email": ["This field is required."], "Username": ["This field is required. "], "Password": ["此字段为必填项。"]。 虽然所有字段都已填写。

模型

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)

【问题讨论】:

为什么将用户作为数据传入? self.serializer_class(data=user) 而不是 data=request.data? 我在这里看到了...谢谢。 thinkster.io/tutorials/django-json-api/authentication 此外,DRF 提供了一个CreateAPIView,您可以将其用于仅创建端点。 cdrf.co/3.9/rest_framework.generics/CreateAPIView.html 【参考方案1】:

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

不过,我们需要解决一件事。注意来自的响应如何 “注册”请求在根目录下包含所有用户信息 等级。我们的客户希望这些信息被命名为 “用户。”为此,我们需要创建一个自定义 DRF 渲染器。

所以不要发布这个:

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

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


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

【讨论】:

以上是关于“这是必填栏。” DRF的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework render_form & 必填字段

Drf03 / drf版本认证权限

DRF模块

drf面试题及总结

DRF 缓存解决方案 drf-extensions / redis

Drf03 /呼啦圈网页初步实现drf筛选视图(源码实现)