Python Django admin:继承基类字段,以便用于在保存时设置模型的字段

Python Django admin:继承基类字段,以便用于在保存时设置模型的字段,python,django,django-admin,Python,Django,Django Admin,我有蛋糕模型。BakedCake具有Cake的外键,并包含一个datetime类型的已创建的utc字段 假设我有CupCake、LemonCake、CheeseCake模型,每个模型都有一个外键字段baked_cake来模拟BakedCake,因为它们都有这个行为和许多其他行为,它们都继承自相同的基类BaseModel 现在,在杯形蛋糕、柠檬蛋糕、奶酪蛋糕的Django管理界面中,我们希望显示一个未烘焙蛋糕的列表,因此该列表要短得多,更容易选择。因此,我们宁愿显示一个蛋糕列表,然后一旦用户选择了

我有蛋糕模型。BakedCake具有Cake的外键,并包含一个datetime类型的已创建的utc字段

假设我有CupCake、LemonCake、CheeseCake模型,每个模型都有一个外键字段baked_cake来模拟BakedCake,因为它们都有这个行为和许多其他行为,它们都继承自相同的基类BaseModel

现在,在杯形蛋糕、柠檬蛋糕、奶酪蛋糕的Django管理界面中,我们希望显示一个未烘焙蛋糕的列表,因此该列表要短得多,更容易选择。因此,我们宁愿显示一个蛋糕列表,然后一旦用户选择了一个蛋糕,我们就使用当前的日期时间和业务逻辑来设置适当的烘焙蛋糕保存

演示代码:

-models.py 类别Cakemodels.模型: name=models.CharFieldBar名称,最大长度=200,unique=True BakedCakemodels类。模型: cake=models.ForeignKeyCake,on_delete=models.PROTECT 已创建\u utc=models.DateTimeField 类BaseModelmodels。模型: 烘焙蛋糕=models.ForeignKeyBakedCake,on_delete=models.PROTECT -这里还有很多其他常见的业务逻辑- 类别CupCakeBaseModel: 自定义字段=models.CharFieldExample1,最大长度=200,唯一性=True LemonCakeBaseModel类: other_field=models.BooleanFieldExample2,默认值=True, CheeseCakeBaseModel类: 另一个_字段=SmallFloatFieldExample3, -管理员 类baseAdmin.ModelAdmin: def get_formself,request,obj=None,**kwargs: form=super.get\u formrequest,obj,**kwargs此表单对象没有.fields属性 form.fields=[x代表form.fields中的x,如果x!=“烘焙蛋糕”] form.fields+=“蛋糕” 报税表 @admin.registerCupCake 类CupCakeAdminBaseAdmin: 通过 @admin.RegisterRemoncake LemonCakeAdminBaseAdmin类: 通过 @admin.registerCheeseCake CheeseCakeAdminBaseAdmin类: 通过 很遗憾,form对象上不存在form.fields。如何替换基本ModelAdmin类的字段,使其派生类也继承这些更改

总结 我想做的不是在管理界面中显示原始模型的字段,而是显示另一个模型的备用字段,然后在保存时使用业务逻辑选择适当的原始字段。这需要在多个模型中发生,因此需要从基础模型继承逻辑


注意:使用Django3时,这种模型管理类的设置至少在Django3.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_实例。。。方法与你的逻辑

字段如何难以选择?我在模型定义中看不到任何名为bar的字段。你错过了吗@运行_race@markwalker_很难选择,因为业务逻辑是基于时间的,包含大量的历史条目,这些条目大多不相关,并且使用某些规则,列表可以从数千个减少到大约50个选择框。@JPG抱歉,这个问题有点混乱,我对它进行了编辑以使其更清晰。从技术上讲,您可以自己定制表单-参见,其中还提到您可以获得默认表单,然后对其进行定制。我自己也没有试过,所以没有把这篇文章作为一个答案,但这可能会让你走上正确的方向。祝你好运非常感谢你,工作做得很好!您是如何知道form.base_字段的?