Debdut Goswami
Debdut Goswami

Reputation: 1379

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)

Upvotes: 4

Views: 625

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476624

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.

Upvotes: 4

Related Questions