【问题标题】:How to get id of the user that modified inline models in Django admin?如何获取在 Django admin 中修改内联模型的用户的 ID?
【发布时间】:2018-08-17 09:49:56
【问题描述】:

我有这些 Django 模型(用于酿造的最少数据):

# models.py
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author)

class AuditLog(models.Model):
    user = models.ForeignKey(User)  # standard User model
    info = JSONField(default=dict)

我知道如何在 AuthorAdmin 中为 Books 创建内联管理员,但问题是,我需要保存 AuditLog 以及有关谁添加了每个内联对象的信息。

我知道我可以做这样的事情来让用户保存作者:

# admin.py
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    inlines = [BookInline]

    def save_model(self, request, obj, form, change):
        AuditLog.objects.create(user=request.user, info={'blah': 'blahblah'})
        super().save_model(request, obj, form, change)

但是我应该怎么做才能保存有关使用内联表单集添加新书(例如,一段时间后)的用户的信息? BaseInlineFormSet 方法不支持这个。

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    我设法像这样做我想做的事:

    # forms.py
    class BookInlineFormset(forms.BaseInlineFormset):
        def save_new(self, form, commit=True):
            if commit and hasattr(form, '_context'):
                context = form._context
                user = context['request'].user
                AuditLog.objects.create(user=user)
                # The Proper Way™ is probably to send a custom signal instead.
            return super().save_new(form, commit)
    
    
    # admin.py
    class BookInline(admin.TabularInline):
        formset = forms.BookInlineFormset
        model = Book # you know the drill 
    
    @admin.register(Author)
    class AuthorAdmin(admin.ModelAdmin):
        inlines = [BookInline]
    
        def save_model(self, request, obj, form, change):
            AuditLog.objects.create(user=request.user, info={'blah': 'blahblah'})
            super().save_model(request, obj, form, change)
    
        def save_formset(self, request, form, formset, change):
            context = {'request', request}
            form._context = context  # just in case
            for form in formset:
                form._context = context
            super().save_formset(request, form, formset, change)
    

    【讨论】:

      【解决方案2】:

      ModelAdmin 和 InlineAdmin 都派生自 BaseModelAdmin,因此您也可以将 save_model 添加到 BookInline。

      【讨论】:

      • 不幸的是 save_model 是在 ModelAdmin 而不是 BaseModelAdmin 中定义的,所以 InlineAdmin 既不继承它也不继承使用它的逻辑。但我刚刚意识到我可以在AuthorAdmin 上重新定义save_formset 并开始在那里挖掘。
      • 你说得对,我只是在阅读源代码并快速滚动,意识到 save_model 仅在 ModelAdmin 中定义:-)
      猜你喜欢
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 2017-10-26
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      相关资源
      最近更新 更多