Automatically Add Logged In User Under 'created_by' and 'updated_by' to Model in Django Rest Framework
Tags: django, drf, djangorestframework, python
Published: 2022-11-05 08:32:12

In some application, we need to track which user added or updated the data in the system. So here we will see how to do this job in the background without any user input. 

**Required setup:** 
I hope you already have Django and the Django Rest Framework installed. If not, please install these first.

run - 
```
pip install Django 
pip install djangorestframework 
``` 

**Settings:**   
In your `settings.py` add 'rest_framework' and your internal apps e.g. 'api'.  

```py
INSTALLED_APPS = [
    #......

    # third-party packages
    'rest_framework',

    # internal apps
    'api',
]
```

**Write models:**   
Define your applications model in `models.py`  
```py
from django.db import models
from django.conf import settings

class Student(models.Model):
    name = models.CharField(max_length=180)
    programme = models.CharField(max_length=250)
    batch = models.SmallIntegerField()
    roll = models.SmallIntegerField()
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, related_name='created_by', blank=True, null=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, related_name='updated_by', blank=True, null=True)

``` 

**Write Serializers:**   
Inside your application, add a file called `serializers.py` and define a serializer class for your model as follows:  
```py
from rest_framework import serializers
from .models import Student

class StudentModelSerializer(serializers.ModelSerializer):
    created_by = serializers.StringRelatedField(default=serializers.CurrentUserDefault(), read_only=True)
    updated_by = serializers.StringRelatedField(default=serializers.CurrentUserDefault(), read_only=True)
    class Meta:
        model = Student
        fields = ['id', 'name', 'programme', 'batch', 'roll', 'created_by', 'updated_by']
        
```

**Admin:**   
You can register your model in `admin.py` in case you want to add data from the Django admin panel: 
```py
from django.contrib import admin
from .models import Student

@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'programme', 'batch', 'roll']

``` 

**View:**  
Now, write your `view.py`, and please make sure to add authentication as we have to work with users:
```py
from .models import Student
from .serializers import StudentModelSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.authentication import SessionAuthentication


class StudentModelViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)

    def perform_update(self, serializer):
        serializer.save(updated_by=self.request.user)

``` 

**URLs:**   
If you didn't define URLs for your views, then define it in `urls.py`.
```py
from django.contrib import admin
from django.urls import path, include 
from rest_framework.routers import DefaultRouter
from api.views import *  

# Create Router Object
router = DefaultRouter()

# Register View Class with Router
router.register('student', StudentModelViewSet, basename='student_')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
    path('auth/', include('rest_framework.urls', namespace='rest_framework'))
]

``` 

**Make Migrations:**   
Migration is necessary after changes in models.  

run - 
```
python manage.py makemigrations 
python manage.py migrate
```


**Users:**   
So this is what we are working for; to add a logged-in user automatically, you must have users registered in your system. So if you don't have any registered users, then add some. If you are using the Django default system, then you can manage users from the Django admin panel. 

**It's time to see the outcomes.**    


Go to the URL in browser:  
![Go to the URL in browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/clu0txi92hgnzmt3fah0.png)

Login to a user:  
![Login to a user](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oe1omfo54aely81ltzwv.png)

Add a new data:  
![Add a new data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05bxgt3786f595ktgfnk.png)


Look at the data, automatically added logged user info to `created_by` field:  
![Look at the data, automatically added logged user info to created_by field](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u1byu1yazz77ry9mhxfu.png)


Now update a data:  
![Now update a data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu6dvkt1r51i1eavvj54.png)


Look at the data, automatically added logged user info to `updated_by` field:  
![Look at the data, automatically added logged user info to updated_by field](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gad4ozum6loppguclzd.png)