如何在Model Serializer的创建方法中设置序列化程序自定义字段?

时间:2018-08-05 16:43:55

标签: django django-rest-framework serializer

我正在使用一个非常简单的模型,但是我被困在这里。我只想要创建用户后,我给他发送了令牌。我创建了一个custome序列化器字段。 这是我的序列化程序类。

         **`1`   `3`   `5`   `7`   `9`  `11`
          <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>**
      1     6     7     7     8    NA    NA
      2     6     7    13    13    14    NA
      3     9    10    10     8    NA    NA
      4     4     3     5     3    NA    NA
      5     3     2     5     5     6    NA
      6     7     7     5     4     5     5
      7     9     5     8     8    NA    NA
      8     6     6     7    NA     7    NA
      9    NA     6     5     5    NA    NA
     10     6     7     6     4     7     6
      # ... with 70 more rows

这是我的CreateAPIView

class UserCreateSerializer(serializers.ModelSerializer):
    token = serializers.CharField(allow_blank=True, read_only=True)
    password = serializers.CharField(min_length=8, write_only=True)
    class Meta:
        model = get_user_model()
        fields = ('id',
                  'username',
                  'password',
                  'token',
                  )

    def create(self, validated_data):
        uname = validated_data['username']
        password = validated_data['password']
        user = get_user_model().objects.create(
            username=uname,
        )
        user.set_password(password)
        user.save()

        data = self.get_initial()
        data['token'] = Token.objects.create(user=user)

        return user

每当我向其发布请求时,它都不会使用令牌来响应我,它始终会给出没有令牌的响应。

class UserCreateAPIView(CreateAPIView):
    serializer_class = UserCreateSerializer
    permission_classes = [AllowAny]

1 个答案:

答案 0 :(得分:1)

source code of Token model

定义为

class Token(models.Model):
        """
        The default authorization token model.
        """
        key = models.CharField(_("Key"), max_length=40, primary_key=True)
        user = models.OneToOneField(
            settings.AUTH_USER_MODEL, related_name='auth_token',
            on_delete=models.CASCADE, verbose_name=_("User")
        )
        created = models.DateTimeField(_("Created"), auto_now_add=True)

因此, user_instance.auth_token.key 将返回相应的KEY。

根据序列化程序,您可以通过将 source 参数引用为

class UserCreateSerializer(serializers.ModelSerializer):
    token = serializers.CharField(
        allow_blank=True, read_only=True, source='auth_token.key')
    # your code


    def create(self, validated_data):
        # your code
        user.refresh_from_db()
        return user


更新
为什么 refresh_from_db()
在您的create()方法中,首先要创建User对象,并将其分配给user变量。那时user.auth_token.key将是None,因为还没有创建Token。然后,您将创建一个与Token相对应的User。但是,它不会反映在user变量上(那里没有 auto-refresh 功能)。因此,user.auth_token.key仍将是None user 方法中使用相同的to_representation对象/实例表示最终数据。这就是为什么最初没有显示Token的原因。
refresh_from_db() ,顾名思义,它刷新了数据库中的值,因此得到了user.auth_token.key