【问题标题】:Make BooleanField required in Django Rest Framework在 Django Rest Framework 中使 BooleanField 成为必需
【发布时间】:2013-08-27 12:49:13
【问题描述】:

我有一个带有布尔字段的模型,我想用 Django rest 框架反序列化它,并且我希望序列化程序在发布请求中缺少一个字段时抱怨。然而,事实并非如此。它默默地将缺少的布尔值解释为 False。

class UserProfile(models.Model):
    """
     Message between two users
"""
     user = models.OneToOneField(User, verbose_name="django authentication user", related_name='user_profile')
     newsletter = models.BooleanField(null=False)
     research = models.BooleanField(null=False)

模型是用这样的序列化器创建的:

 class UserProfileSerializer(serializers.ModelSerializer):
 research = BooleanField(source='research', required=True)
 newsletter = BooleanField(source='newsletter', required=True)

 class Meta:
    model = UserProfile
    fields = ('research', 'newsletter')

在我看来,我也在创建一个用户,所以我有一些手动步骤:

 def post(self, request, format=None):
    userprofile_serializer = UserProfileSerializer(data=request.DATA)
    reg_serializer = RegistrationSerializer(data=request.DATA)
    phone_serializer = PhoneSerializer(data=request.DATA)


    errors = {}
    if userprofile_serializer.is_valid() and reg_serializer.is_valid() and phone_serializer.is_valid():
        user = reg_serializer.save()
        data = reg_serializer.data

        user_profile = userprofile_serializer.object
        user_profile.user = user
        userprofile_serializer.save()

        return Response(data, status=status.HTTP_201_CREATED)

    errors.update(reg_serializer.errors)
    # ...
    return Response(errors, status=status.HTTP_400_BAD_REQUEST)

但是,下面的测试用例失败了,因为其余框架没有抱怨缺少参数,而是在 from_native 中插入了一个 False

     def test_error_missing_flag(self):
    data = {'username': "test", 'password': "123test", 'email': 'test@me.com',
            'newsletter': 'true', 'uuid': self.uuid}

    response = self.client.post(reverse('app_register'), data)
    # should complain that 'research' is not found
    self.assertTrue('research' in response.data)

如果我用整数字段替换我的“研究”字段,则序列化程序会按预期失败。有什么想法吗?

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    添加

    your_field = serializers.NullBooleanField(required=False)
    

    serializer.

    就是这样。它会工作:)

    【讨论】:

    • 我认为你也可以添加 serializers.BooleanField(required=False, allow_null=True)
    【解决方案2】:

    布尔字段和required 参数存在问题。现在应该在 master 中修复。

    看到这个问题:https://github.com/tomchristie/django-rest-framework/issues/1004

    【讨论】:

    • 谢谢。刚刚调试它,也找到了默认值。大师有多稳?我可以将其用于生产吗?
    • 如果你反对一个特定的提交,那么生活应该是美好的。不要只跟踪 master - 下一个版本计划为 2.4.0,这意味着 API 的一些部分将通过弃用过程。这非常严格,但你不会想在没有意识到的情况下升级到它。
    • 干杯。现在我坚持使用 2.3.7,但像这样覆盖 BooleanField:class NonDefaultBooleanField(BooleanField): default = None
    • 嗨,我使用的是 DRF 3.1.1,除非我使用 serializers.NullBooleanField(),否则这似乎仍然是个问题。即,如果字段未提交给序列化器,则使用带有“required=True”的serializers.BooleanField 不会引发错误。
    【解决方案3】:

    对于阅读了@Tom 2013 年接受的答案并发现这仍然不起作用的任何人,这是因为此行为适用于 HTML 表单输入。这是original issue

    要将 serializers.BooleanField 与 JSON 有效负载一起使用,请通过执行 request.POST.dict() 将您的 request.POST 转换为 Python dict,并在初始化时将其传递给您的序列化程序。

    【讨论】:

      【解决方案4】:

      创建一个新的自定义类:

      from rest_framework import serializers
      
      class RequirableBooleanField(serializers.BooleanField):
          default_empty_html = serializers.empty
      

      现在,您可以使用:

      research = RequirableBooleanField(required=True)
      

      research = RequirableBooleanField(required=False)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-06
        • 2018-06-25
        • 1970-01-01
        • 1970-01-01
        • 2013-11-15
        • 1970-01-01
        • 2020-02-03
        • 2016-09-18
        相关资源
        最近更新 更多