【问题标题】:Store who updated Django Model from admin存储从管理员更新 Django 模型的人
【发布时间】:2021-09-18 09:21:37
【问题描述】:

我有一个用例,其中仅从 django 管理员插入和更新数据。现在,我有多个用户可以访问 django 管理页面。我希望能够在 django 管理页面中存储准确更新或创建记录的人。

理想情况下,我想为现有模型添加一个单独的列。

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)

【问题讨论】:

标签: django django-models django-admin


【解决方案1】:

您可以覆盖.save_model(…) method [Django-doc] 以设置.updated_by.created_by 字段,具体取决于changeTrue 还是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)

如果大量模型需要此功能,您可以制作一个 mixin,然后将其用于各种模型:

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)

然后使用 mixin:

class LinkAdmin(CreateUpdateUserAdminMixin, admin.ModelAdmin):
    pass

class OtherModelAdmin(CreateUpdateUserAdminMixin, admin.ModelAdmin):
    pass

admin.site.register(Links, LinkAdmin)
admin.site.register(OtherModel, OtherModelAdmin)

注意:通常 Django 模型被赋予一个单数名称,所以Link而不是Links

【讨论】:

  • 完美。这正是我想要的
  • 如何防止该字段出现在 Django 管理表单中?
  • @DebdutGoswami:在created_byupdated_by 的模型字段中设置editable=False