I am using rest_framework.response method to send objects of multiple django models. However, the response containts backslashes with quotes. Here is my view:
@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)
The json response I am getting is:
{"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":"[]"}
Is there any other way to do it? What I understand is, it is encoding the data twice (once in serializers.serialize and then in response.Response). But I dont want that. I want nested objects. Something like this:
{"attendances":[{"model": "mainApp.attendance", "pk": 5, "fields": {"ArrivalTime": "2016-06-27T18:45:46.355Z", "DepartureTime": null, "User": 4, "ArrivalImei": "1",...
Can anyone tell me how to achieve this? Thanks in advance.
Those backslashes are escape characters. They are escaping the special characters inside of the string associated with JSON response. You have to use JSON. parse to parse that JSON string into a JSON object.
JSON is a format that encodes an object to a string. On the transmission of data or storing is a file, data need to be in byte strings, but as complex objects are in JSON format. Serialization converts these objects into byte strings which is JSON serialization.
Using replace() Function Along with The json. Loads() Function to Remove Backslash from Json String in Python.
I finally managed to solve it. The problem was, when the objects were serialized using serializer.serialize() function, I was getting a string. Whereas I wanted a dict. I had to use json.loads() to convert the string into a dictionary as:
responseData['user'] = json.loads(userObject)
And everything worked as I wanted to. Now, the response is something like:
{
"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"
}
},
As you identified, you are double-serializing everything by converting your querysets to JSON strings, adding them to a dict and then passing the dict to response.Response
.
Much of the point of using Django REST Framework is that is handles the serialization for you, so the goal should be to avoid serializing to JSON strings yourself in the api view.
To make best use of DRF you need to define a ModelSerializer
for each of the models you want to return in the response.
One thing that is confusing in DRF is the terminology. Normally when we talk about "serialization" it means converting objects to a string (i.e. JSON). But in DRF, serializers actually convert complex objects -> primitive objects. So when you use a ModelSerializer
to "serialize" your queryset it does not produce a JSON string, but rather primitive python objects (a dict) that can then be serialized, in the conventional sense, to a JSON string without errors. This 'real' serialization is done for you by the Response
class.
So I suggest as a starting point:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With