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

Django admin视图中readonly字段如何设置固定随机默认值

问题原因

你的推测完全正确,两次调用生成随机值的核心逻辑是:

  1. Admin新增页面渲染阶段,为了展示只读的code字段,会调用一次create_code生成初始值。但Django的readonly_fields默认只会将字段值渲染为纯文本,不会生成对应的表单输入控件,所以这个初始值不会随着表单提交到后端。
  2. 提交保存阶段,Django检测到表单提交的数据中没有code字段的有效值,会再次调用字段定义的default=create_code生成新值,最终存入数据库的就是第二次生成的值。

解决方案

方案1:仅调整Admin配置(适合仅在Admin后台创建Project的场景)

重写ProjectAdmin的save_model方法,直接读取表单渲染阶段生成的初始值赋值给实例,避免二次生成:

# admin.py
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
    fields = ('name', 'code')
    readonly_fields = ('code', )

    def save_model(self, request, obj, form, change):
        # 仅新增对象时从表单初始数据取第一次生成的code
        if not change:
            obj.code = form.initial.get('code', create_code())
        super().save_model(request, obj, form, change)

方案2:调整模型保存逻辑(通用方案,适配所有创建Project的场景)

把code生成逻辑放到模型的save方法中,仅在首次保存无code的时候生成,从根源避免重复调用:

  1. 首先修改models.py中的字段定义和save逻辑:
# models.py
class Project(models.Model):
    name = models.CharField("Project name", max_length=255)
    # 移除default配置,新增blank=True允许初始为空
    code = models.CharField("Code", max_length=10, editable=False, blank=True)

    def save(self, *args, **kwargs):
        # 仅首次保存、且没有code值的时候才生成
        if not self.pk and not self.code:
            self.code = create_code()
        super().save(*args, **kwargs)
  1. 如果需要保留Admin新增页面预展示code的效果,再给ProjectAdmin增加初始值生成逻辑即可:
# admin.py
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
    fields = ('name', 'code')
    readonly_fields = ('code', )

    def get_initial(self, request):
        initial = super().get_initial(request)
        initial['code'] = create_code()
        return initial

内容的提问来源于stack exchange,提问作者Bismarck Gomes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 04:06:04