具有反斜杠的 Json 序列化数据
Posted
技术标签:
【中文标题】具有反斜杠的 Json 序列化数据【英文标题】:Json serialized data having backslashes 【发布时间】:2016-11-30 05:35:03 【问题描述】:我正在使用 rest_framework.response 方法来发送多个 django 模型的对象。但是,响应包含带引号的反斜杠。这是我的看法:
@api_view()
def myfunctions(request,id):
responseData =
userObject = TifUser.objects.filter(id=id)
attendances = Attendance.objects.filter(User=userObject)
leaves = Leave.objects.filter(User=userObject)
odds = ODD.objects.filter(User=userObject)
printjobs = PrintJob.objects.filter(User=userObject)
issues = Issue.objects.filter(User=userObject)
#serialize into json
userObject = serializers.serialize("json", userObject)
attendances = serializers.serialize("json",attendances)
leaves = serializers.serialize("json",leaves)
odds = serializers.serialize("json",odds)
printjobs = serializers.serialize("json",printjobs)
issues = serializers.serialize("json",issues)
#set responseData dictionary values
responseData['user'] = userObject
responseData['attendances'] = attendances
responseData['leaves'] = leaves
responseData['odds'] = odds
responseData['printjobs'] = printjobs
responseData['issues'] = issues
#responseData['attendances'] = userObject
return response.Response(responseData)
我得到的 json 响应是:
"attendances":"[\"model\": \"mainApp.attendance\", \"pk\": 5, \"fields\": \"ArrivalTime\": \"2016-06-27T18:45:46.355Z\", \"DepartureTime\": null, \"User\": 4, \"ArrivalImei\": \"1\", \"DepartureImei\": null, \"Hash\": \"321f059c-4230-417a-adff-f0035097c85d\", \"model\": \"mainApp.attendance\", \"pk\": 13, \"fields\": \"ArrivalTime\": \"2016-07-18T15:40:39.943Z\", \"DepartureTime\": null, \"User\": 4, \"ArrivalImei\": \"2\", \"DepartureImei\": null, \"Hash\": \"e61fad3e-8238-46fc-b09b-8b7754d43f3b\"]","printjobs":"[\"model\": \"mainApp.printjob\", \"pk\": 1, \"fields\": \"User\": 4, \"DateAdded\": \"2016-07-18\", \"Status\": \"disapproved\", \"Person\": 5, \"Level\": \"boss\", \"Client\": \"someone\", \"HandledBy\": \"tester\", \"SanctionedBy\": \"myself\", \"AdvancePayment\": 0, \"FinalPayment\": 1000, \"PaymentNumber\": 1, \"Remarks\": \"something\"]","odds":"[]","user":"[\"model\": \"mainApp.tifuser\", \"pk\": 4, \"fields\": \"AuthUser\": 7, \"Head\": null, \"Boss\": null, \"ClrLevel\": 1, \"Department\": 1, \"DesignationName\": 1, \"Name\": \"tester\", \"IsRegistered\": true, \"DateOfBirth\": \"1222-11-11\", \"Anniversary\": \"2001-12-22\", \"Mobile\": \"2134567890\", \"gcmDevice\": null, \"FatherName\": \"\", \"MotherName\": \"\", \"PersonalEmail\": \"\", \"Gender\": \"Male\", \"CurrentAddress\": \"\", \"PermanentAddress\": \"\", \"PANNumber\": \"\", \"AadharCardNumber\": null, \"BloodGroup\": \"\", \"MaritalStatus\": \"Married\", \"ProfilePhoto\": \"\", \"Imei\": \"\"]","leaves":"[]","issues":"[]"
还有其他方法吗?我的理解是,它对数据进行了两次编码(一次在 serializers.serialize 中,然后在 response.Response 中)。但我不想那样。我想要嵌套对象。像这样的:
"attendances":["model": "mainApp.attendance", "pk": 5, "fields": "ArrivalTime": "2016-06-27T18:45:46.355Z", "DepartureTime": null, "User": 4, "ArrivalImei": "1",...
谁能告诉我如何做到这一点?提前致谢。
【问题讨论】:
如果你print
你的json响应,反斜杠消失了吗?
@ShangWang 是的,打印时没有反斜杠。只有在我得到它们的响应中。
然后您将获得转义引号的 json 字符串。可以result = json.loads(json_response)
看看result
是不是你想要的数据结构吗?
@ShangWang 也显示反斜杠。
尝试这样返回,返回response.Response(serializers.serialize('json' ,responseData))
【参考方案1】:
我终于设法解决了。问题是,当使用 serializer.serialize() 函数序列化对象时,我得到了一个字符串。而我想要一个字典。我不得不使用 json.loads() 将字符串转换为字典:
responseData['user'] = json.loads(userObject)
一切都如我所愿。现在,响应类似于:
"attendances": [
"pk": 5,
"model": "mainApp.attendance",
"fields":
"DepartureTime": null,
"Hash": "321f059c-4230-417a-adff-f0035097c85d",
"ArrivalImei": "1",
"DepartureImei": null,
"User": 4,
"ArrivalTime": "2016-06-27T18:45:46.355Z"
,
【讨论】:
序列化为json是没有意义的,然后将其反序列化并将其添加到您的responseData
dict中,然后让rest框架再次对其进行序列化【参考方案2】:
正如您所确定的,您通过将查询集转换为 JSON 字符串、将它们添加到字典然后将字典传递给 response.Response
来对所有内容进行双重序列化。
使用 Django REST Framework 的主要目的是为您处理序列化,因此目标应该是避免在 api 视图中自己序列化为 JSON 字符串。
为了充分利用 DRF,您需要为要在响应中返回的每个模型定义一个 ModelSerializer
。
在 DRF 中令人困惑的一件事是术语。通常,当我们谈论“序列化”时,它意味着将对象转换为字符串(即 JSON)。但在 DRF 中,序列化程序实际上是转换复杂对象 -> 原始对象。因此,当您使用ModelSerializer
来“序列化”您的查询集时,它不会生成 JSON 字符串,而是生成原始的 Python 对象(字典),然后可以按照传统意义上将其序列化为 JSON 字符串而不会出现错误。这个“真正的”序列化是由Response
类为您完成的。
所以我建议作为一个起点:
class TifUserSerializer(serializers.ModelSerializer):
class Meta:
model = TifUser
class AttendanceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Attendance
class LeaveSerializer(serializers.ModelSerializer):
class Meta:
model = Leave
class ODDSerializer(serializers.ModelSerializer):
class Meta:
model = ODD
class PrintJobSerializer(serializers.ModelSerializer):
class Meta:
model = PrintJob
class IssueSerializer(serializers.ModelSerializer):
class Meta:
model = Issue
@api_view()
def myfunctions(request, id):
users = TifUser.objects.filter(id=id)
user_serializer = TifUserSerializer(users, many=True)
attendances = Attendance.objects.filter(User=userObject)
attendance_serializer = AttendanceSerializer(attendancesv, context='request': request)
leaves = Leave.objects.filter(User=userObject)
leave_serializer = LeaveSerializer(leaves, many=True)
odds = ODD.objects.filter(User=userObject)
odd_serializer = ODDSerializer(odds, many=True)
printjobs = PrintJob.objects.filter(User=userObject)
printjob_serializer = PrintJobSerializer(printjobs, many=True)
issues = Issue.objects.filter(User=userObject)
issue_serializer = IssueSerializer(issues, many=True)
responseData =
responseData['user'] = user_serializer.data
responseData['attendances'] = attendance_serializer.data
responseData['leaves'] = leave_serializer.data
responseData['odds'] = odd_serializer.data
responseData['printjobs'] = printjob_serializer.data
responseData['issues'] = issue_serializer.data
return response.Response(responseData)
【讨论】:
这是我一开始尝试做的。但我收到以下错误: 不是 JSON 可序列化的。这就是为什么我必须这样做。 @nikssardana 与 DRF 有点混淆的地方通常是“序列化”意味着将对象转换为字符串(即 JSON),但 DRF 序列化程序实际上转换复杂对象 -> 原始对象(即 JSON 格式支持的原语:字典、列表、整数、浮点数、字符串)。然后,这些原始对象可以通过Response
类序列化为 JSON 字符串。所以你需要一个 DRF 序列化器,它将你的 Django 模型实例转换为原始对象django-rest-framework.org/api-guide/serializers
你想要的是ModelSerializer
django-rest-framework.org/api-guide/serializers/…
非常感谢您提供的信息。是的,我以前用过这些,但我不知道为什么我没有考虑在这种情况下使用。
我使用了attendance_serializer = AttendanceSerializer(attendances,many=True)
。现在我收到一个错误:对象不是 json 可序列化的。以上是关于具有反斜杠的 Json 序列化数据的主要内容,如果未能解决你的问题,请参考以下文章