Search code examples
djangorestserializationdjango-rest-frameworkdjango-views

Django rest framework where to write complex logic in serializer.py or views.py?


I am new to Django Rest Framework. Using serializer and views a simple CRUD is easy. When the logics increase, it is quite confusing where to write logics in serializer or views.
Some developers do prefer "Thick serializer and thin views" and some developers "Thick views and thin serializer".
Maybe this is not a big issue and I think it is up to the developer whether to write more on views or serializer, but as a newbie what will be your suggestion to follow? Should I write more on views or serializer?
There are many answers on Django View Template but can not find a satisfying answer for Django Rest Framework.
Thoughts of experienced developers will be highly appreciated. Thank you.


Solution

  • Personally I prefer to have the business logic separated from both view and serializer. I usually create a new class with the business logic which can be used in both serializer and view based on necessity. Basically I treat it as a service. Reason for that is:

    1. Makes the code cleaner(no thick and thin stuff).
    2. Writing tests for those business logic is easier.
    3. You can use that this business logic service in both view and serializer, depending on your need.
    4. while testing APIs, you can mock those buiness logic if needed.
    5. Reuse any logic in multiple places.

    An example would be like this:

    class BusinessLogicService(object):
    
        def __init__(self, request):
           self.request = request
    
        def do_some_logical_ops(self, data_required_one, data_required_two):
            # do processing
            return processed_data
    

    Example usage in serializer:

    class SomeSerializer(serializer.Serialize):
         ...
         def create(self, validated_data):
             business_logic_data = BusinessLogicService(self.request).do_some_logical_ops(**validated_data)
             return Model.objects.create(**business_logic_data)