我的模型中有一个fee
DecimalField,如下所示:
class CardTypes(models.Model):
class Meta:
db_table = "card_types"
verbose_name = 'Card Type'
verbose_name_plural = 'Card Types'
name = models.CharField("Name", max_length=255, null=True, blank=True)
fee = models.DecimalField("Fee", max_digits=65, decimal_places=0, default=0)
image_url = models.CharField("Image Url", max_length=255, null=True, blank=True)
deleted_at = models.DateTimeField(null=True, blank=True)
def card_type_image(self):
if self.image_url is not None:
return mark_safe('<img src="%s" width="130" height="90" />' % (self.image_url))
else:
return "No image yet"
card_type_image.short_description = 'image'
def fee_convert(self):
if self.fee is not None:
currency = Currency.objects.get(pk=1)
return Decimal(self.fee / pow(10, currency.decimals))
else:
return None
fee_convert.short_description = 'Fee'
我设置DecimalField("Fee", max_digits=65, decimal_places=0, default=0)
是因为我想将其保存在DB上而没有小数位,但是我想在管理站点上与它转换后的方法进行交互。
例如,如果数据库中的费用为0.00005,则在管理员中它将仅显示并保存值为5(因为currency.decimals = 5)
我设法显示转换后的值,并在管理端将其保存为5,如下所示:
class CardTypeAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CardTypeAdminForm, self).__init__(*args, **kwargs)
if self.instance.fee is not None:
try:
self.initial['fee'] = self.instance.fee_convert()
except:
pass
def clean_fee(self):
if self.cleaned_data['fee'] is not None:
currency = Currency.objects.get(pk=1)
data = Decimal(self.cleaned_data['fee'] * pow(10, currency.decimals))
else:
data = None
return data
class CardTypesAdmin(admin.ModelAdmin):
list_display = ('name', 'card_type_image',)
list_display_links = ('name', 'card_type_image', )
form = CardTypeAdminForm
fields = (
'id',
'name',
'fee',
'image_url',
'card_type_image',
'deleted_at',
)
readonly_fields = (
'id',
'card_type_image',
'deleted_at'
)
admin.site.register(CardTypes, CardTypesAdmin)
但是在我要输入admin值为0.005或小数点后的费用字段的情况下(应该起作用,因为在数据库中它将另存为500),但admin验证返回以下验证错误:
确保小数位数不超过0。
因为管理表单字段继承了来自Model Field的验证,我是否仍然可以覆盖它?
答案 0 :(得分:0)
我找到了一种方法,可以通过替换费用表格字段的形式创建新字段:
class CardTypeAdminForm(forms.ModelForm):
currency = Currency.objects.get(pk=1)
fee = forms.DecimalField(required=False, decimal_places=currency.decimals)
def __init__(self, *args, **kwargs):
super(CardTypeAdminForm, self).__init__(*args, **kwargs)
if self.instance.fee is not None:
try:
self.initial['fee'] = self.instance.fee_convert()
except:
pass
def clean_fee(self):
if self.cleaned_data['fee'] is not None:
currency = Currency.objects.get(pk=1)
data = Decimal(self.cleaned_data['fee'] * pow(10, currency.decimals))
else:
data = None
return data
class Meta:
model = CardTypes
exclude = ['fee']
class CardTypesAdmin(admin.ModelAdmin):
list_display = ('name', 'card_type_image',)
list_display_links = ('name', 'card_type_image', )
form = CardTypeAdminForm
fields = (
'id',
'name',
'fee',
'image_url',
'card_type_image',
'deleted_at',
)
readonly_fields = (
'id',
'card_type_image',
'deleted_at'
)
def save_model(self, request, obj, form, change):
obj.fee = form.cleaned_data['fee']
return super(CardTypesAdmin, self).save_model(request, obj, form, change)