save(commit=False) cannot save objects but can return objects in a list and is used to customize the submitted inline objects in Django Admin. *As far as I researched and experimented, using save(commit=False)
is the easiest way to customize the submitted inline objects in Django Admin.
save()
equivalent to save(commit=True)
can save objects, then can retrun objects in a list and is not used to customize the submitted inline objects in Django Admin because more queries are run.
For example, there are Category
model and Product
model which has the foreign key of Category
model as shown below:
# "my_app/models.py"
class Category(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
def __str__(self):
return self.name
And, there is overridden save_formset() with print(formset.save())
in Category
admin which has Product
inline as shown below. *save_formset()
is run when changing inline objects:
# "my_app/admin.py"
class ProductInline(admin.TabularInline):
model = Product
extra = 0
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
inlines = (ProductInline,)
def save_formset(self, request, form, formset, change):
print(formset.save()) # Here
And, there is Fruits
category which has Apple
and Orange
products as shown below:
Now, I change Apple
to Apple Juice
and Orange
to Orange Juice
by clicking on SAVE as shown below:
Then, Apple
is changed to Apple Juice
and Orange
is changed to Orange Juice
as shown below:
Then, 2 inline objects are returned in a list on console as shown below:
[<Product: Apple Juice>, <Product: Orange Juice>]
And, two inline objects are saved by two UPDATE
queries according to the PostgreSQL logs below. *You can see my answer explaining about how to log queries in PostgreSQL:
Next, I use formset.save(commit=False)
as shown below:
# "my_app/admin.py"
# ...
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
inlines = (ProductInline,)
def save_formset(self, request, form, formset, change):
print(formset.save(commit=False)) # Here
Now again, I change Apple
to Apple Juice
and Orange
to Orange Juice
by clicking on SAVE as shown below:
Then, Apple
is not changed to Apple Juice
and Orange
is not changed to Orange Juice
as shown below:
Then, 2 inline objects are returned in a list on console as shown below:
[<Product: Apple Juice>, <Product: Orange Juice>]
Then, two inline objects are not saved by two UPDATE
queries according to the PostgreSQL logs below:
Next, I make the submitted names of inline objects uppercase with formset.save(commit=False)
as shown below. *Again, save(commit=False)
is used to customize the submitted inline objects in Django Admin:
# "my_app/admin.py"
# ...
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
inlines = (ProductInline,)
def save_formset(self, request, form, formset, change):
for object in formset.save(commit=False): # Here
object.name = object.name.upper()
formset.save()
Now, I add Vegetable
category, Cucumber
and Potato
products by clicking on SAVE as shown below:
Then, Cucumber
and Potato
are made uppercase as shown below:
And, two inline objects are saved by two INSERT
queries according to the PostgreSQL logs below:
Next, I make the submitted names of inline objects uppercase with formset.save()
as shown below. *Again, save()
equivalent to save(commit=True)
is not used to customize the submitted inline objects in Django Admin because more queries are run:
# "my_app/admin.py"
# ...
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
inlines = (ProductInline,)
def save_formset(self, request, form, formset, change):
for object in formset.save(): # Here
object.name = object.name.upper()
formset.save()
Now again, I add Vegetable
category, Cucumber
and Potato
products by clicking on SAVE as shown below:
Then again, Cucumber
and Potato
are made uppercase as shown below:
And first, two inline objects with Cucumber
and Potato
are saved by two INSERT
, and second, two inline objects with CUCUMBER
and POTATO
are saved by two UPDATE
queries according to the PostgreSQL logs below:
So, don't use save()
to customize the submitted inline objects in Django Admin because more queries are run. Instead, you should use save(commit=False)
to customize the submitted inline objects in Django Admin.
form = forms.SampleForm(instance = models.Sample)
) – Irma