问题描述
我在今年 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 序列化程序应该能够自动识别这些值 - null
、true
和 false
- 我不必手动替换它们或者是我的模型中缺少某些东西吗?我试图通过 print(instance.values('justice')[0]['justice'])
打印值,以便我可以检查但抛出相同的异常。但是我的其他 JSON 数据 case
很好,我可以用 print(instance.values('case')[0]['case'])
打印它,我的假设是因为它没有 null
、true
和 false
价值。
这是我的模型:
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 格式。