You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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)

操作流程与现象:

  1. 在「修改水果」页面的「名称」输入框中输入orange
    输入orange的页面截图
  2. 修改完成后,名称成功从APPLE转为大写的ORANGE
    修改后名称为ORANGE的页面截图

但PostgreSQL日志显示出现了一条无用的UPDATE查询:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:50:40