I have created a Mixin for the serializer classes. I wanted to create several serializer for different tasks. So, I need for special actions special serializers.
# mixins.py
class SerializerClassMixin:
serializer_create_class = None
serializer_details_class = None
def get_serializer_class(self):
if self.action == "create":
return self.serializer_create_class
elif self.action == "retrieve":
return self.serializer_details_class
return super().get_serializer_class()
For the actions create and retrieve (get details), I have created new class attributes to call the serializer. The return super().get_serializer_class()
tells the Mixin to use the get_serializer_class()
for any other actions.
These are all possible actions:
- list (GET)
- retrieve (GET)
- create (POST)
- update (PUT)
- partial_update (PATCH)
- destroy (DELETE)
For my project, I have decided to create two serializers: CreateSerializer and DetailSerializer.
# views.py
class IssueViewSet(SerializerClassMixin, viewsets.ModelViewSet):
serializer_class = IssueDetailSerializer
serializer_create_class = IssueCreateSerializer
serializer_detail_class = IssueDetailSerializer
For these project I have created two different serializers: IssueCreateSerializer and IssueDetailSerializer.
Why have I used the IssueDetailSerializer for all other actions? If I use the IssueCreateSerializer for update action (PUT or PATCH) of the attributes like description
or assigned_to
, the result in Postman is a ValidationError because the IssueCreateSerializer checks if the name
, tag
, state
and priority
in one issue already exists. And if you do not change the name
, tag
, state
and priority
the update is failing.
In IssueDetailSerializer I do not do any validation.
To visualize the serializers:
# serializers.py
class IssueCreateSerializer(serializers.ModelSerializer):
"""create and lists Issues
validate if the issue already exists"""
class Meta:
model = Issue
fields = [
"id",
"assigned_to",
"name",
"description",
"tag",
"state",
"priority",
]
def validate(self, attrs):
if (
self.context["view"]
.issue.filter(
name=attrs["name"],
tag=attrs["tag"],
state=attrs["state"],
priority=attrs["priority"],
)
.exists()
):
raise serializers.ValidationError("Attention! This issue exists already.")
return attrs
class IssueDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Issue
fields = [
"id",
"author",
"assigned_to",
"name",
"description",
"tag",
"state",
"priority",
"project",
"created_time",
]
Top comments (0)