0

I have Model, like:

 def SomeModel(models.Model):
     serial_num = models.IntegerField(unique=True)
     count = models.IntegerField()

And have to create 2 url which will work with this model. But, there are have to be 2 different serializers. For example:

  • For first url user’data have to has both fileds (serial_num and count) For second url users’data have to has only one field (count).
  • In second case serial_num will be generated in Serializers class.

Is this good practice to make 2 different serializers for one model?

And also question, what about validation?

Field “count” is depends on another model. I thought put validate into serializer class. But I don’t want to have 2 the same blocks of validation code in 2 different serializers classes (for both urls).

6
  • I don't see a problem with using multiple serializers for 1 model - you only need separate views for each serializers for different behavior. Commented Dec 27, 2018 at 13:00
  • But what about validate? Both os serializers have to validate field "count" which depends on another model. Commented Dec 27, 2018 at 13:11
  • yep, you write different validations for each serializer. Of course, you can make it as a separate function and just call it inside serializers, to by DRY. Commented Dec 27, 2018 at 13:15
  • Then you can write a separate class (aka a Mixin) that encapsulates this validation and then apply this mixin (inherit from this class) to both serializers Commented Dec 27, 2018 at 13:17
  • What is better way to validate models object? In Model's class or in Serializer class? Commented Dec 27, 2018 at 13:54

3 Answers 3

1

Create two serializers and assign each of your views to that specific serializer.

for example, imagine you have two path like path1 and path2:

class MyModelViewSet(ModelViewSet):
    serializer_class = Serializer1
    queryset = YourModel.objects.all()

    @action(methods=['post'], detail=False, url_path='path1', serializer_class=Serializer1)
    def path1_view(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        .....

    @action(methods=['post'], detail=False, url_path='path2', serializer_class=Serializer2)
    def path2_view(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        .....

and for serializers:

class Serializer1(ModelSerializer):
    class Meta:
        model = SomeModel
        fields = ('serial_num', 'count',)

class Serializer2(ModelSerializer):
    class Meta:
        model = SomeModel
        fields = ('count',)

    def validate(self, attrs):
        # Update attrs with serial_num here
        return attrs
Sign up to request clarification or add additional context in comments.

1 Comment

For viewset actions like list, create, update, etc you must override get_serializer_class() method and return the correct serializer class based on the self.action attribute. Check this
0

You should use two serializers and use inheritance for common validation logic.

Comments

-1

I've found approach which may be more usefull. Use services for business logic. Example can read here: https://github.com/HackSoftware/django-styleguide#examples

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.