Django Serializer 的问题涉及嵌套的 JSON 与 null 和布尔值 true 或 false

问题描述

我在今年 4 月下旬开始使用 Django,这是我第一次处理大量 JSONB 数据。希望有人能就这个异常的原因提供一些意见:

格式错误:TypeError:JSON 对象必须是 str、bytes 或 bytearray,而不是 dict

所以我检查了我的数据(我使用的是 Postgresql,它来自数据库视图,列名“decision”是 JSONB 数据类型),JSON 数据实际上看起来很完美:

{
  "some_id": "long-uuid-string","case": {
    "name": "CaseA","description": "DescriptionA","case_date": "2021-06-23"
  },"justice": {
    "name": "JusticeA","decision": [
      {
        "name": "DecisionA","decision_date": "2021-06-23","decision_flag": true,"decision_comment": null
      }
    ]
  }
}

但我注意到了 "decision_flag": true"decision_comment": null,但我认为 Django+Python 应该能够转换,但看起来没有。

我的理解是 Django 序列化程序应该能够自动识别这些值 - nulltruefalse - 我不必手动替换它们或者是我的模型中缺少某些东西吗?我试图通过 print(instance.values('justice')[0]['justice']) 打印值,以便我可以检查但抛出相同的异常。但是我的其他 JSON 数据 case 很好,我可以用 print(instance.values('case')[0]['case']) 打印它,我的假设是因为它没有 nulltruefalse价值。

这是我的模型

class Justice(models.Model):
    some_id = models.UUIDField(unique=True)
    case = models.JSONField()
    justice = models.JSONField()
    submission = models.JSONField()
    evaluation = models.JSONField()
    litigation = models.JSONField()
    denial = models.JSONField()
    triel = models.JSONField()

    def __str__(self):
        return str(self.some_id)

这是我的视图

class JusticeView(APIView):
  serializer_class = JusticeSerializer

  def get_object(self,request,**kwargs):
    some_id = self.kwargs['some_id']
    try:
      obj = get_object_or_404(Justice,pk=some_id)
    except Justice.DoesNotExist:
      return Response(status=status.HTTP_404_NOT_FOUND)
    return obj

  def get(self,**kwargs):
    data = self.get_object()
    serializer = JusticeSerializer(data)

    return Response(serializer.data)

这是我的序列化程序

class JusticeSerializer(serializers.ModelSerializer):

    case = serializers.JSONField()
    justice = serializers.JSONField()

    class Meta:
        model = Justice
        fields = '__all__'

希望能在这里得到一些帮助。干杯。

解决方法

我就是这样解决这个问题的。我不确定这是否是最好的方法,但至少这是有效的 - 如果有更好的方法 - Django 方式 - 我肯定会考虑。

我通过将所有 JSONField 更改为 TextField 来修改我的模型。请注意,此模型仅适用于我的数据库视图 - 这不是一个实际的表,但我的“view_definition”中的所有源都将 JSONB 作为数据类型。

class Justice(models.Model):
    some_id = models.UUIDField(unique=True)
    case = models.TextField(null=True)
    justice = models.TextField(null=True)
    submission = models.TextField(null=True)
    evaluation = models.TextField(null=True)
    litigation = models.TextField(null=True)
    denial = models.TextField(null=True)
    triel = models.TextField(null=True)

    def __str__(self):
        return str(self.some_id)

对于 JSONB 类型的每一列,我都使用 serializers.JSONField() 保持我的序列化程序不变。我的数据库视图保持不变,其中 JSON 列采用 JSONB 格式。