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
相关产品推荐
相关产品推荐

