django admin delete objects in inlines in save_model method

5k views Asked by At

I have two related (via foreignkey relation) models and created admin model for parent with inlines. In several cases (edited in admin by boolean field), i need to delete all previous objects (inlines) and create new ones. I've tried to make it with save_model, where i can get all current object's properties and decide if i need to recreate (inline) objects. models:

class Model1(models.Model):
    reformat = models.BooleanField(default=False)
    ...
class Model2(models.Model):
    model1 = ForeignKey(Model1, related_name='model2')
    ...

admin:

class Model2Inline(admin.TabularInline):
    model = Model2

class Model1Admin(admin.ModelAdmin):
    inlines = [Model2Inline]
    def save_model(self, request, obj, form, change):
        super(Model1Admin, self).save_model(request, obj, form, change)
        if obj.reformat:
            obj.model2.all().delete()
            # creating new objects
            ...
        obj.save()

But if i try to delete these objects in model_save method i get ValidationError. Is there other possibilities to solve this problem?

1

There are 1 answers

1
Caspar On BEST ANSWER

I came across this problem as well, and, after an hour or two of banging my head against the wall, solved it by overriding save_formset() on the admin object instead of save_model() and doing the required manipulation after calling the super class's save_formset() method. Doing it this way means the models which you are deleting are still present when the formset is saved, so you don't get the validation error.

Here's what it might look like in the example you gave:

class Model2Inline(admin.TabularInline):
    model = Model2

class Model1Admin(admin.ModelAdmin):
    inlines = [Model2Inline]
    def save_formset(self, request, form, formset, change):
        super(Model1Admin, self).save_formset(request, form, formset, change)
        if formset.model is Model2:
            obj = formset.instance
            if obj.reformat:
                obj.model2.all().delete()
                # creating new objects
                ...
            obj.save()