1

Hi I need to be able to add the current user to an inline object as it is being saved or modified. I am using django-admin dashboard as this application is not public facing.

class Med(models.Model):
    generic_name = models.CharField(max_length=33)
    last_updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL)

    def save_model(self, request, obj, form, change):
            try:
                obj.last_updated_by = request.user
            except AttributeError:
                obj.last_updated_by = None
            super().save_model(request, obj, form, change)

class Comment(models.Model):
    text = models.TextField(("Comment"), max_length = 1000, null=False)
    med = models.ForeignKey(Med, related_name="comments", on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL)

    def save_model(self, request, obj, form, change):
        obj.user = request.user
        super().save_model(request, obj, form, change)

class CommentInline(admin.TabularInline):
    model = Comment
    extra = 0

class Med(admin.ModelAdmin):
    inlines = (CommentInline,)

I have tried to override the save_related function as well, but it seems that the CommentFormSet objects it contains are ALL of them vs just the one being modified or saved:

'_queryset': <QuerySet [<Comment: test>, <Comment: another test>]>,

A few of the SO posts on this topic were stale and didn't have enough information to extrapolate a working save_related implementation either.

hpca01
  • 370
  • 4
  • 15

2 Answers2

3

I think the method you are looking for overriding is save_formset. This method is called once per inline in your AdminModel, and saves the inline objects.

You could use it like this:

class Med(admin.ModelAdmin):
    inlines = (CommentInline,)

    def save_formset(self, request, form, formset, change):
        for inline_form in formset.forms:
            if inline_form.has_changed():
                inline_form.instance.user = request.user
        super().save_formset(request, form, formset, change)

This would add current user to those objects that are being modified.

bertucho
  • 656
  • 4
  • 7
  • i Added `id` field as **read only** but now, `id` is missing every time while update a form and it cause an error. while updating inline data. – Devang Hingu Feb 03 '21 at 11:09
2

Heads up, this solution also worked for me:

class MedAdmin(admin.ModelAdmin):
    inlines = (CommentInline,)

    def save_related(self, request, form, formsets, change):
        for formset in formsets:
            list_comment = formset.save(commit=False)
            for comment in list_comment:
                comment.user = request.user
        return super().save_related(request, form, formsets, change)
hpca01
  • 370
  • 4
  • 15