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

Django字段仅创建时可编辑需求咨询:会计账户货币字段设置

当然可行!这种需求在Django Admin里非常常见,尤其是像会计账户这类需要固定初始配置的场景,完全可以实现。下面给你两种简单可靠的实现方案,还有额外的安全保障建议:

方案一:通过Admin的get_readonly_fields控制(推荐)

这种方法不需要修改模型,只需要在Admin类里重写get_readonly_fields方法,根据当前是创建还是更新操作动态设置只读字段。

1. 先定义你的会计账户模型

from django.db import models

class Account(models.Model):
    account_name = models.CharField(max_length=100, verbose_name="账户名称")
    # 这里用CharField存货币代码(比如'USD'/'CNY'),也可以换成ForeignKey关联货币表
    currency = models.CharField(max_length=3, verbose_name="货币类型")
    balance = models.DecimalField(max_digits=12, decimal_places=2, verbose_name="账户余额")

    def __str__(self):
        return self.account_name

2. 配置Admin类实现动态只读

from django.contrib import admin
from .models import Account

@admin.register(Account)
class AccountAdmin(admin.ModelAdmin):
    list_display = ('account_name', 'currency', 'balance')
    # 默认只读字段(如果有的话)
    readonly_fields = ()

    def get_readonly_fields(self, request, obj=None):
        # obj存在代表是更新操作,把currency加入只读字段
        if obj:
            return self.readonly_fields + ('currency',)
        # obj不存在代表是创建操作,保持currency可编辑
        return self.readonly_fields
方案二:通过自定义表单禁用字段

这种方法是在Admin使用的表单里,根据实例是否存在来禁用currency字段,前端会直接灰掉该输入框,体验更直观。

1. 自定义Admin表单

from django import forms
from .models import Account

class AccountAdminForm(forms.ModelForm):
    class Meta:
        model = Account
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 如果是更新操作(实例已存在),禁用currency字段
        if self.instance.pk:
            self.fields['currency'].disabled = True

2. 在Admin类中使用这个表单

from django.contrib import admin
from .models import Account
from .forms import AccountAdminForm

@admin.register(Account)
class AccountAdmin(admin.ModelAdmin):
    form = AccountAdminForm
    list_display = ('account_name', 'currency', 'balance')
额外保障:模型层面防止非法修改

上面两种方法只限制了Admin后台的操作,但如果有人通过API、命令行或者其他方式修改数据,还是可能篡改currency字段。为了会计数据的准确性,建议在模型层面再加一层保护:

class Account(models.Model):
    # 字段定义同之前...

    def save(self, *args, **kwargs):
        # 如果是更新操作,检查currency是否被修改
        if self.pk:
            original_account = Account.objects.get(pk=self.pk)
            if original_account.currency != self.currency:
                # 可以抛出错误阻止修改,或者直接忽略修改(恢复原值)
                raise ValueError("会计账户的货币类型一旦创建无法修改")
                # 或者用 self.currency = original_account.currency 来静默恢复
        super().save(*args, **kwargs)

两种Admin方案都能满足你的需求,选哪种看个人习惯;模型层面的保护则是为了全方位保障数据安全,毕竟会计数据的准确性至关重要。

内容的提问来源于stack exchange,提问作者Shachar Web

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:58:52