在Django Admin重写response_change()时如何消除无用UPDATE查询?
问题描述
我在FruitAdmin中重写了response_change()方法,添加代码将用户在「修改水果」页面输入的名称转为大写,代码如下:
# "store/admin.py" from django.contrib import admin from .models import Fruit @admin.register(Fruit) class FruitAdmin(admin.ModelAdmin): def response_change(self, request, obj): obj.name = obj.name.upper() obj.save() return super().response_change(request, obj)
操作流程与现象:
- 在「修改水果」页面的「名称」输入框中输入
orange
- 修改完成后,名称成功从
APPLE转为大写的ORANGE
但PostgreSQL日志显示出现了一条无用的UPDATE查询:
请问如何消除这条无用的UPDATE查询?
解决方法
问题根源在于response_change()是Django Admin完成模型保存后才触发的方法,此时Admin已经执行了一次UPDATE操作,你在这个方法里调用obj.save()又会触发第二次UPDATE,这就导致了多余的查询。可以通过以下两种更合适的方式替代:
方法1:重写save_model()方法
save_model()是Admin处理模型保存的核心钩子,在数据写入数据库前执行,直接在这里处理名称转大写,只会触发一次UPDATE:
from django.contrib import admin from .models import Fruit @admin.register(Fruit) class FruitAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): # 在保存前将名称转为大写 obj.name = obj.name.upper() super().save_model(request, obj, form, change)
方法2:在模型的clean()方法中处理
如果希望所有场景下(不仅是Admin)水果名称都自动转大写,可以在模型层添加clean()方法:
# "store/models.py" from django.db import models class Fruit(models.Model): name = models.CharField(max_length=100) def clean(self): # 清理时将名称转为大写 self.name = self.name.upper() super().clean()
这种方式下,无论通过Admin还是其他方式修改数据,都会先执行clean处理,Admin保存时只会触发一次UPDATE。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

