I am a bit frustrated with this problem using the Django Rest Framework:
I am using a viewset, with a custom serializer
. This serializer has its depth set to 1
. When i query this viewset I get the correct representation of data for example:
data = {
id: 1,
issue_name: 'This is a problem',
status: {
id: 3,
name: 'todo'
}
}
The problem comes in when I need to update the status. For example if I want to select another status for this issue, for example:
status_new = {
id: 4,
name: 'done'
}
I send the following PATCH back to the server, this is the output:
data = {
id: 1,
issue_name: 'This is a problem',
status: {
id: 4,
name: 'done'
}
}
However, the status does not get updated. Infact, it is not even a part of the validated_data dictionary. I have read that nested relations are read-only. Could someone please tell me what I need to do this in a simple way?
Would really be obliged.
Thanks in advance
As stated in the documentation, you will need to write your own
create()
andupdate()
methods in your serializer to support writable nested data.You will also need to explicitly add the status field instead of using the
depth
argument otherwise I believe it won't be automatically added tovalidated_data
.EDIT: Maybe I was a bit short on the details: what you want to do is override update in ModelIssueSerializer. This will basically intercept the PATCH/PUT requests on the serializer level. Then get the new status and assign it to the instance like this:
The reason I mentioned in the comment that you might need to add a
StatusSerializer
field is for getting status intovalidated_data
. If I remember correctly, if you only usedepth
then nested objects might not get serialized inside theupdate()
/create()
methods (although I might be mistaken on that). In any case, adding theStatusSerializer
field is just the explicit form of usingdepth=1
I would assume that your models mimic your serializer's data. Also, I would assume that you have a one to many relation with the status(es) but you don't need to create them via the issue serializer, you have a different endpoint for that. In such a case, you might get away with a SlugRelatedField.
Another valid solution would be to leave here the foreign key value and deal with the display name on the front-end, via a ui-select or select2 component - the RESTfull approach: you are handling Issue objects which have references to Status objects. In an Angular front-end app, you would query all the statuses from the back-end on a specific route and then you will display the proper descriptive name based on the foreign key value form Issue.
Let me know how is this working out for you.