Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin - Auto save current user to model via inlines?

I have the following and it throws an error when I attempt to upload a document via the admin page for Proceeding. How can I auto populate the entered_by field for the Document model when using an inline?

Error: IntegrityError at /admin/myapp/proceeding/6/change/ (1048, "Column 'entered_by_id' cannot be null")

# models.py
class Proceeding(models.model):
    date = models.DateField()
    entered_by = models.ForeignKey(User)

class Document(TimeStampedUserModel):
    proceeding = models.ForeignKey(Proceeding)
    document = models.FileField(upload_to='documents/')
    entered_by = models.ForeignKey(User)


#admin.py
class DocumentAdmin(admin.ModelAdmin):
    fields = ('proceeding', 'document', )
    list_display = ('proceeding', 'entered_by', )

    def save_model(self, request, obj, form, change):
        instance = form.save(commit=False)
        instance.entered_by = request.user
        instance.save()
        form.save_m2m()
        return instance
    def save_formset(self, request, form, formset, change):
        def set_user(instance):
            instance.entered_by = request.user
            instance.save()
        if formset.model == Document:
            instances = formset.save(commit=False)
            map(set_user, instances)
            formset.save_m2m()
            return instances
        else:
            return formset.save()

class DocumentInline(admin.TabularInline):
    model = Document
    fields = (
        'proceeding',
        'document',
    )
    extra = 0

class ProceedingAdmin(admin.ModelAdmin):
    inlines = [DocumentInline, ]
    fields = ('date',)
    list_display = ('date', 'entered_by',  )

    def save_model(self, request, obj, form, change):
        instance = form.save(commit=False)
        instance.entered_by = request.user
        instance.save()
        form.save_m2m()
        return instance
    def save_formset(self, request, form, formset, change):
        def set_user(instance):
            instance.entered_by = request.user
            instance.save()
        if formset.model == Proceeding:
            instances = formset.save(commit=False)
            map(set_user, instances)
            formset.save_m2m()
            return instances
        else:
            return formset.save()
like image 503
Fish Avatar asked Dec 05 '25 07:12

Fish


1 Answers

The example in the docs for save_formset shows how to do this. Save the formset with commit=False, then iterate through the instance and set the entered_by field to request.user.

class ProceedingAdmin(admin.ModelAdmin):
    ...
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for obj in formset.deleted_objects:
            obj.delete()
        for instance in instances:
            instance.entered_by = request.user
            instance.save()
        formset.save_m2m()

Note that your DocumentAdmin doesn't need a save_formset method, since it doesn't have any inlines.

like image 115
Alasdair Avatar answered Dec 07 '25 19:12

Alasdair



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!