Search code examples
pythondjangodjango-rest-frameworkdjango-signals

Django Rest Framework ModelSerializers - Handling create and update


I have some models in my Django database. Each model is created or updated through the DRF API. As a result, I have serializers (for every model) that handle the create, update and partial_update on the models.

A main part of the handling includes the following action:

def handle():
    if created:
        model.owner = request.user
        model.other_fields = other fields
        model.save()
    else:
        model.other_fields = other fields
        model.save()

Additionally, I need to create log entries whenever a model is saved, with request.user.

Log.objects.create(user=request.user, model=model, created=timezone.now())

I cannot use signals to create log entries, as the post_save signal does not have the request object.

How should I handle this?

  • Should I create a custom signal and send it every time I create or update a model?
  • Should I call a function in serializer's create and update to log the model?

Solution

  • Avoid using signals. The best approach is

    OPTION 1

    • call a function in serializer's create and update to log the model

    But, do it using a mixin.

    class LogSerializerMixin(object):
    
       def create_log(self):
           //do logic over here
           // get your request over here using self
           // get your model using self.instance
           Log.objects.create(user=request.user, model=model, created=timezone.now())
    

    Then in your serializers

    Serializer1(LogSerializerMixin, serializers.ModelSerializer):
    
        def create(self):
            // creation logic over here
            self.create_log()
    
        def update(self, data):
            // update logic over here
            self.create_log()
    

    Another serializer.

    Serializer2(LogSerializerMixin, serializers.ModelSerializer):
    
        def create(self):
            // creation logic over here
            self.create_log()
    
        def update(self, data):
            // update logic over here
            self.create_log()
    

    OPTION 2

    • Rewrite save model method and add log creation logic over there.