python - Django admin:继承基类字段,以便在保存时设置模型的字段
问题描述
我有模型Cake
。BakedCake
有一个外键Cake
并包含一个created_utc
日期时间类型的字段。
假设我有模型,,,,CupCake
每个模型都有一个外键字段LemonCake
,因为它们共享此行为和许多其他行为,它们都继承自同一个基类。CheeseCake
baked_cake
BakedCake
BaseModel
现在在 , , 的 Django 管理界面中,CupCake
我们希望显示s 而不是s 的列表,因此该列表更短且更容易从中选择。因此,我们宁愿显示s 的列表,然后一旦用户选择了 a ,我们使用当前的日期时间和业务逻辑来设置适当的保存时。LemonCake
CheeseCake
Cake
BakedCake
cake
cake
baked_caked
演示代码:
# --- models.py
class Cake(models.Model):
name = models.CharField("Bar name", max_length=200, unique=True)
class BakedCake(models.Model):
cake = models.ForeignKey(Cake, on_delete=models.PROTECT)
created_utc = models.DateTimeField()
class BaseModel(models.Model):
baked_cake = models.ForeignKey(BakedCake, on_delete=models.PROTECT)
# -- Lots of other common business logic here --
class CupCake(BaseModel):
custom_field = models.CharField("Example1", max_length=200, unique=True)
class LemonCake(BaseModel):
other_field = models.BooleanField("Example2", default=True, )
class CheeseCake(BaseModel):
another_field = SmallFloatField("Example3", )
# --- admin.py
class BaseAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs) # This form object does not have .fields attribute
form.fields = [x for x in form.fields if x != 'baked_cake']
form.fields += 'cake'
return form
@admin.register(CupCake)
class CupCakeAdmin(BaseAdmin):
pass
@admin.register(LemonCake)
class LemonCakeAdmin(BaseAdmin):
pass
@admin.register(CheeseCake)
class CheeseCakeAdmin(BaseAdmin):
pass
不幸的是,该对象form.fields
不存在。form
如何替换基ModelAdmin
类的字段,使其派生类也继承这些更改?
概括
我要做的不是在管理界面中显示原始模型的字段,而是显示另一个模型的备用字段,然后在保存时使用业务逻辑来选择适当的原始字段。这需要在多个模型中发生,因此从基本模型继承逻辑。
注意:使用 Django 3
解决方案
这种模型管理类的设置绝对有效(至少在 Django 3.1 中)
from django.contrib import admin
from django import forms
from .models import Cake
class AbstractModelAdmin(admin.ModelAdmin):
def get_baked_cake_instance(self, cake):
return "something"
def get_form(self, request, obj=None, change=False, **kwargs):
form = forms.modelform_factory(self.model, exclude=("baked_cake",))
form.base_fields["cake"] = forms.ModelChoiceField(queryset=Cake.objects.all())
return form
def save_form(self, request, form, change):
model_instance = form.save(commit=False)
model_instance.baked_cake = self.get_baked_cake_instance(form.cleaned_data["cake"])
return model_instance
然后,注册你的模型,
admin.site.register(CupCake, AbstractModelAdmin)
admin.site.register(LemonCake, AbstractModelAdmin)
admin.site.register(CheeseCake, AbstractModelAdmin)
示例截图
注意:不要忘记get_baked_cake_instance(...)
用你的逻辑完成方法!!!
推荐阅读
- windows - powershell 检查是否存在多个文件
- powershell - Powershell 用户输入
- python - 替换pyspark中的unicode字符
- .net - 重叠条件
- javascript - 如何在对象的深层嵌套数组中创建唯一的对象数组?
- pine-script - 如何用 syminfo.tickerid 实现 JMA,但是没有 JMA 功能
- aws-lambda - Cloudfront 与本地开发环境
- pine-script - 交易视图默认的指标,从 pinescript 创建的指标不匹配
- ldap - OpenLDAP for Windows 2.4.49 openldap.log 不工作
- android - 如何从近到远排序距离?