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)