我有一个继承自Mezzanine“可显示”模型的模型,该模型本身继承自“Slugged”模型。在Slugged模型中有以下几行:
gen_description = models.BooleanField(_("Generate description"),
help_text=_("If checked, the description will be automatically "
"generated from content. Uncheck if you want to manually "
"set a custom description."), default=True)
对于我创建的模型,我希望默认行为不自动创建描述。当然,覆盖这个领域本身并不会起作用。
我的第一个猜测是:
def __init__(self,*args,**kwargs):
self.gen_description = False
super(CyclesMaterial,self).__init__(*args,**kwargs)
但没有运气。我真的没想到这会起作用,但还是试了一下。
试图找到我找到this question的解决方案。所以我试着在我的模型中这样做:
def __init__(self,*args,**kwargs):
kwargs.setdefault('gen_description', False)
super(CyclesMaterial,self).__init__(*args,**kwargs)
但它不起作用。
如何实现我想要的目标?有可能吗?
答案 0 :(得分:3)
在模型实例化之前,它的字段是Field
子类的实际实例(例如BooleanField
)。直接赋值不起作用。只有在模型的__init__
方法中,它们才会被实际值替换。
这就是为什么你的第一个方法不起作用的原因:你在调用super(CyclesMaterial, self).__init__(*args, **kwargs)
之前尝试分配一个值,并覆盖BooleanField
实例。模型不再将gen_description
视为模型字段,而是将其视为常规对象属性。
我刚刚测试了你的第二个解决方案,这些是我的结果:
# No value set
>>> c = CyclesMaterial()
>>> c.gen_description
False
# Value set to `True`
>>> c = CyclesMaterial(gen_description=True)
>>> c.gen_description
True
# Value set to `False`
>>> c = CyclesMaterial(gen_description=False)
>>> c.gen_description
False
这正是我期望的行为,如果我理解你的问题,你想要的行为。如果未设置gen_description
,则不会kwargs
,而kwargs.set_default('gen_description', False)
会将其设置为False
。如果已设置,则它将在kwargs
中,并且它的值将被保留并直接在模型上设置。
修改强>:
如果您希望在管理界面或其他表单中更改默认值,则必须在表单中手动覆盖它。 ModelForm
是根据类定义生成的,您无法更改字段的选项,也无需为所有超类更改字段的选项。因此,您必须更改表单的initial
值,覆盖生成的默认值:
# either this:
form = CyclesMaterialForm(initial={'gen_description': False})
# or this:
class CyclesMaterialForm(forms.ModelForm):
gen_description = forms.BooleanField(_('Generate description'),
help_text=_("If checked, the description will be automatically "
"generated from content. Uncheck if you want to manually "
"set a custom description."), initial=False, required=False)
然后更改表单的所有实例以使用第一个解决方案,或者更改为第二个解决方案中提供的CyclesMaterialForm
实例。