How to get id of the user that modified inline models in Django admin?

时间:2018-03-08 22:10:30

标签: django django-admin

I have these Django models (minimal data for brewity):

# 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)

I know how to create inline admin for Books in AuthorAdmin but the problem is, I need to save AuditLog with information about who added each of the inline objects.

I know I can make something like this to get the user upon saving Author:

# 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)

But what should I do to save the info about the user that added a new Book (eg. after some time) using the inline formset? BaseInlineFormSet methods don't support this.

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

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