【问题标题】:Django REST Framework a boolean/None value in the request is getting set to FalseDjango REST Framework 请求中的布尔值/无值设置为 False
【发布时间】:2023-03-25 13:26:01
【问题描述】:

我有一个名为 'active' 的值,它在 Django 模型中默认为 'True'。我不想设置这个值并允许它由默认操作创建,但是,在 Django REST 框架中的某个地方,它在到达序列化程序中的验证方法之前被设置为“False”。如何防止此操作或至少捕获它,以便将不存在的“活动”值设置为“真”?

我只是发布相关代码,这是一个复杂的系统,完整的代码会让人不知所措。状态列来自这个抽象类模型。如您所见,只有活动列默认为 True。

class StatusModelMixin(models.Model):
    active = models.BooleanField(
        verbose_name=_("Active"), default=True,
        help_text=_("If checked the record is active."))
    soft_delete = models.BooleanField(
        verbose_name=_("Hide"), default=False,
        help_text=_("If checked the record is removed from all queries."))
    purge = models.BooleanField(
        verbose_name=_("Purge"), default=False,
        help_text=_("If checked the record will be deleted."))

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        """
        Intercept the save and update the 'purge' and 'soft_delete' objects.
        This save will not be called during bulk creates and updates, so the
        logic below will need to be duplicated for each object in bulk
        operations.
        """
        if self.purge: self.soft_delete = True
        if self.soft_delete: self.active = False
        super(StatusModelMixin, self).save(*args, **kwargs)

这只是受我遇到的问题影响的序列化程序类之一。你可以看到我的一些测试代码没有解决这个问题。

class OrganizationSerializer(serializers.ModelSerializer):
    user = serializers.HyperlinkedRelatedField(
        view_name='user-detail', read_only=True)
    uri = serializers.HyperlinkedIdentityField(
        view_name='organization-detail')
    #active = serializers.BooleanField(default=True, required=True)

    class Meta:
        model = Organization
        fields = ('id', 'address_01', 'address_02', 'city', 'region',
                  'postal_code', 'country', 'phone', 'fax', 'active',
                  'soft_delete', 'purge', 'ctime', 'mtime', 'institution',
                  'user', 'uri')
        exclude = ('purge',)
        read_only_fields = ('id', 'ctime', 'mtime',)
        depth = 0

    #def validate(self, attrs):
    #    log.debug("attrs: %s", attrs)
    #    return attrs

谢谢

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    好的,所以我刚刚尝试过,实际上模型默认值被忽略了,即使您在序列化程序中指定它也是如此。似乎当没有明确发送该值时,它被忽略了。

    我环顾四周,发现了一个错误报告:

    https://github.com/tomchristie/django-rest-framework/issues/1101

    在解决此问题之前,您可以在视图集中尝试这个丑陋的 hack:

    def get_serializer(self, *args, **kwargs):
        # data may be None
        data = kwargs['data']
        if data is not None:
            data = data.copy() # need to make copy because of immutable QueryDict
            data.setdefault('active', True)
            kwargs['data'] = data
        return super(OrganizationViewSet, self).get_serializer(*args, **kwargs)
    

    【讨论】:

    • "即使您在序列化程序中指定它" 从查看票证来看,我认为部分不正确 - 只是如果序列化程序字段是自动生成的,则默认设置不正确,对吗?
    • 其实在这两种情况下。如果您在序列化程序中设置该字段,它仍然无法解决问题,因此我对其进行了评论。
    • jbub -- 效果很好,谢谢。我将需要在大约 40 个地方执行此操作,因此我可能会为它制作一个 mixin。当休息框架得到修复时,这也将使其易于拉出。再次感谢。
    • @cnobile -- 刚刚注意到kwargs['data']键可能不存在,所以在第三行使用data = kwargs.get('data')会更安全。
    • @jbub -- 我已经猜到这可能会发生并且已经按照你的建议做了。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 2013-11-09
    • 2020-06-23
    • 2014-07-03
    相关资源
    最近更新 更多