Search code examples
djangodjango-modelsdjango-admin

Store who updated Django Model from admin


I have a use case where data is only inserted and updated from django admin. Now, I have multiple users who have access to django admin page. I want to be able to store who exactly updated or created a record in django admin page.

Ideally, I want to add a separate column to an existing model.

models.py

class Links(models.Model):
    link = models.URLField(unique=True)
    created_at = models.DateTimeField(auto_now_add=True)
    created_by = model.ForeignKey(UserModel)
    updated_at = models.DateTimeField(auto_now=True)
    updated_by = model.ForeignKey(UserModel)

Solution

  • You can override the .save_model(…) method [Django-doc] to set the .updated_by and .created_by fields, depending on whether change is True or False:

    from django.contrib import admin
    
    class LinkAdmin(admin.ModelAdmin):
        
        def save_model(self, request, obj, form, change):
            if not change:
                obj.created_by = request.user
            obj.updated_by = request.user
            return super().save_model(request, obj, form, change)
    
    admin.site.register(Links, LinkAdmin)

    If you need this for a large number of models, you can make a mixin, and then use that for all sorts of models:

    class CreateUpdateUserAdminMixin:
        
        def save_model(self, request, obj, form, change):
            if not change:
                obj.created_by = request.user
            obj.updated_by = request.user
            return super().save_model(request, obj, form, change)

    and then use the mixin with:

    class LinkAdmin(CreateUpdateUserAdminMixin, admin.ModelAdmin):
        pass
    
    class OtherModelAdmin(CreateUpdateUserAdminMixin, admin.ModelAdmin):
        pass
    
    admin.site.register(Links, LinkAdmin)
    admin.site.register(OtherModel, OtherModelAdmin)

    Note: normally a Django model is given a singular name, so Link instead of Links.