Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7k
Singe CRUD / request->response Operation two serializers#9630
-
G'Day, Cant seem to find an answer anywhere, so hoping for an idea/solution.
Within my app, depending upon the situation I use different serializers. which serializer is used is dyno-magically determined by the viewsets logic. i.e. I have a view serializer forALL get requests with the creation of the object being dynamic, serializer wise. I have discovered recently that when creating an object, the correct serializer is used, however the serializer that is used for the JSON response is not the one I wish to use. Looking at the code for the create of an object, It uses the same serializer for the create and the JSON return. (or have i looked in the wrong area?)
Is this something I will be required to create a custom solution for? or is there a setting or process I have overlooked somewhere? |
BetaWas this translation helpful?Give feedback.
All reactions
I had this problem a few times and there are a few ways to solve the problem, depending on how much your request schema differs from your response schema. Generally speaking, I think it's a good idea to minimise the differences. I'll describe a few options I've adopted over time.
Example
Let's use a simpleBlogPost
model in an blogging application:
classBlogPost(models.Model):author=models.ForeignKey("auth.User",on_delete=models.CASCADE)title=models.CharField(max_length=255)body=models.TextField()created_at=models.DateTimeField(auto_now_add=True)
When a post of created, the author provides the title and body, and the other fields as derived from the request. …
Replies: 1 comment 4 replies
-
I had this problem a few times and there are a few ways to solve the problem, depending on how much your request schema differs from your response schema. Generally speaking, I think it's a good idea to minimise the differences. I'll describe a few options I've adopted over time. ExampleLet's use a simple classBlogPost(models.Model):author=models.ForeignKey("auth.User",on_delete=models.CASCADE)title=models.CharField(max_length=255)body=models.TextField()created_at=models.DateTimeField(auto_now_add=True) When a post of created, the author provides the title and body, and the other fields as derived from the request. When reading a post, however, we want to display its author and creation date. Solution 1: override the create methodWith the solution you mention, the implementation might look like this: # SerializersclassUserSerializer(serializers.ModelSerializer):classMeta:model=Userfields= ("id","first_name","last_name","username")classCreateBlogPostSerializer(serializers.ModelSerializer):"""Serializer for creating posts."""classMeta:model=BlogPostfields= ("title","body")classBlogPostSerializer(CreateBlogPostSerializer):"""Serializer for reading posts."""author=UserSerializer()classMeta:model=BlogPostfields= ("id","author","title","body","created_at")# viewsclassBlogPostViewSet(CreateModelMixin,RetrieveModelMixin,GenericViewSet):queryset=BlogPost.objects.all()serializer_class=BlogPostSerializerdefcreate(self,request,*args,**kwargs):create_serializer=CreateBlogPostSerializer(data=request.data,context=self.get_serializer_context(), )create_serializer.is_valid(raise_exception=True)post=create_serializer.save(author=self.request.user)response_serializer=self.get_serializer(post)headers=self.get_success_headers(response_serializer.data)returnResponse(response_serializer.data,status=status.HTTP_201_CREATED,headers=headers) We override the
This is however duplicating a fair bit of boilerplate from DRF, so not ideal. Solution 2: override the |
BetaWas this translation helpful?Give feedback.
All reactions
👍 1
-
wow, that's an answer.@browniebroke I really appreciate the time you have taken to assist with my dilemma. I was already leaning towards For completeness I should have included some context, example serialized objects. The "View" serializers use nested serializers for related models whilst the "create/update" serializers are based off of the model. For completeness, Here's the create serialized object. {"name":"string","device_type":0,"model_notes":"string","serial_number":"string","uuid":"string","is_global":true,"is_virtual":true,"device_model":0,"config":"string","organization":0} and the response / view serialized object (ALL get requests and the serializer to use in the CRUD response) {"id":0,"status_icon": {"additionalProp1":"string","additionalProp2":"string","additionalProp3":"string" },"display_name":"string","name":"string","device_type": {"id":0,"display_name":"string","name":"string","url":"string" },"model_notes":"string","serial_number":"string","uuid":"string","is_global":true,"is_virtual":true,"device_model": {"id":0,"display_name":"string","name":"string","url":"string" },"config":"string","rendered_config":"string","inventorydate":"2025-01-25T06:44:36.557Z","context": {"additionalProp1":"string","additionalProp2":"string","additionalProp3":"string" },"created":"2025-01-25T06:44:36.557Z","modified":"2025-01-25T06:44:36.557Z","organization": {"id":0,"display_name":"string","name":"string","url":"string" },"_urls": {"additionalProp1":"string","additionalProp2":"string","additionalProp3":"string" }} |
BetaWas this translation helpful?Give feedback.
All reactions
🎉 1
-
I thought you might mention that, have you tried to use their https://drf-spectacular.readthedocs.io/en/latest/customization.html#step-2-extend-schema It's super flexible and can do almost anything |
BetaWas this translation helpful?Give feedback.
All reactions
-
Yeah am familiar with drf's |
BetaWas this translation helpful?Give feedback.
All reactions
-
Was causally browsing GitHub and stumbled on this. I want to say - I typically have my own workarounds which mirror what is posted, nevertheless I am very glad that this is written here to validate how I usually go about solutioning my APIs. Appreciate the hard work on this project 🫡 |
BetaWas this translation helpful?Give feedback.