【问题标题】:Django Rest Framework ModelSerializer giving error for primary fieldDjango Rest Framework ModelSerializer 为主字段提供错误
【发布时间】:2021-08-08 21:32:28
【问题描述】:

我正在做一个项目,我通过扩展 AbstractBaseUser 和 PermissionMixin 创建了自定义用户,模型类如下。

class User(AbstractBaseUser, PermissionsMixin):
    phone_number = models.CharField(
        primary_key=True, validators=[MinLengthValidator(10)], max_length=10
    )
    password = models.CharField(
        null=False, blank=False, validators=[MinLengthValidator(8)], max_length=225
    )
    date_joined = models.DateTimeField(null=False, blank=False, default=timezone.now)
    last_login = models.DateTimeField(null=True, blank=True)
    last_logout = models.DateTimeField(null=True, blank=True)

    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    USERNAME_FIELD = "phone_number"
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    @staticmethod
    def hash_password(sender, instance, *args, **kwargs):
        if not instance.is_staff and not instance.is_superuser:
            instance.set_password(instance.password)

    def get_token(self):
        return Token.objects.get(user=self)

    def __str__(self):
        return self.phone_number


# signals for Model User
pre_save.connect(User.hash_password, sender=User)

还有下面的ModelSerializer与之对应。

class UserLoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["phone_number", "password"]

现在如果我将帖子数据传递为:-

{
    "phone_number":8888888888,
    "password":12345678
}

我得到了什么:

  • serializer.is_valid() 返回 False。

  • 如果我在做 serializer.is_valid(raise_exception=True) 那么我就是 得到响应:

    { “电话号码”: [ “使用此电话号码的用户已存在。” ] }

我的疑问是:

  • 我知道 8888888888 已经在数据库中,但我仍然想 使用 serializer.validated_data.get('phone_number', None)
  • 访问它
  • 我也想知道原因,为什么会这样,是在演戏 就像我试图插入一条记录,但如果我传递电话号码 比如 8888888887(数据库中不存在),那么它工作正常

【问题讨论】:

  • 你能分享你的 API 视图吗?

标签: django api django-models django-rest-framework django-views


【解决方案1】:

由于phone_number是主键,所以默认有唯一的验证器。

您可以在序列化程序中添加自定义验证器,如下所示。

class UserLoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["phone_number", "password"]
        extra_kwargs = {
            'phone_number': {
                'validators': [MinLengthValidator(10)],
            }
        }

通过仅添加我们需要的验证器,序列化程序仅根据给定的验证器进行验证。如果'validators': [], 设置为空列表,则不会对特定字段执行验证。

我添加了 MinLengthValidator(10) 验证器,您已在 User 模型中使用过它。您可以在此处导入并使用它。

【讨论】:

  • 您的方法有效,但我提出了一些更改建议,请查看并相应更改您的答案。
【解决方案2】:

这是因为phone_number 是主键。主键是唯一字段,因此不能有重复记录。检查here

【讨论】:

  • 我知道,但我没有在数据库中插入任何东西,我只是在请求对象中获取此属性
  • 但您正在检查数据是否有效。所以,它说它不是。检查验证是插入数据库的第一步。如果您尝试插入该数据,它将不会再次允许它。
  • 哦,有什么办法可以摆脱这个吗?我应该在序列化程序子类中定义自定义字段吗?
  • 您可以将 serializer.is_valid() 放入 try-except 结构的内部,这样您就可以在不中断请求的情况下处理错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 2013-08-26
  • 2017-03-21
  • 2015-08-14
  • 2014-09-21
相关资源
最近更新 更多