重写Django admin inline以请求每个实例的formfield_for_dbfield的最简单方法

2024-09-29 23:32:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在Django管理内联中为同一类型的模型字段提供不同的小部件来输入表单字段。在

我在我的shop应用程序中实现了实体属性值范例的一个版本(我尝试了eavdjango,但它不够灵活)。在我的模型中,它是产品参数值(见下面的编辑)。 除了在为参数值对包含一个管理内联时,每个值都使用相同的输入formfield之外,其他一切都按我想要的方式工作。我知道这是默认的Django管理行为,因为它对每个内联行使用相同的formset。在

我有一个我想使用的参数回调函数(get_value_formfield)。我目前有:

class SpecificationValueAdminInline(admin.TabularInline):
model = SpecificationValue
fields = ('parameter', 'value')
readonly_fields = ('parameter',)
max_num = 0

def get_formset(self, request, instance, **kwargs):
    """Take a copy of the instance"""
    self.parent_instance = instance
    return super().get_formset(request, instance, **kwargs)

def formfield_for_dbfield(self, db_field, **kwargs):
    """Override admin function for requesting the formfield"""
    if self.parent_instance and db_field.name == 'value':

        # Notice first() on the end -->
        sv_instance = SpecificationValue.objects.filter(
            product=self.parent_instance).first()
        formfield = sv_instance.parameter.get_value_formfield()
    else:
        formfield = super().formfield_for_dbfield(db_field, **kwargs)
    return formfield

对于每个管理页,formfield_for_dbfield只调用一次。在

如何重写默认行为,以便为每个SpecificationValue实例调用formfield_for_dbfield一次,最好每次都传递实例?在

编辑:

以下是模型布局:

^{pr2}$

Tags: theinstance模型selffordbgetparameter
1条回答
网友
1楼 · 发布于 2024-09-29 23:32:05

我最终解决这个问题的方法是使用Admin内联的form =属性。这将跳过ModelAdmin的表单生成代码:

class SpecificationValueForm(ModelForm):
    class Meta:
        model = SpecificationValue

    def __init__(self, instance=None, **kwargs):
        super().__init__(instance=instance, **kwargs)
        if instance:
            self.fields['value'] = instance.parameter.get_value_formfield()
        else:
            self.fields['value'].disabled = True

class SpecificationValueAdminInline(admin.TabularInline):
    form = SpecificationValueForm

使用像这样的标准表单,带有选项的小部件(例如RadioSelectCheckboxSelectMultiple)在管理界面中的旁边有列表项目符号,因为<ul>没有radiolist类。您几乎可以通过使用AdminRadioSelect(attrs={'class': 'radiolist'})来修复RadioSelect,但是{}没有管理版本,所以我更喜欢一致性。另外,<fieldset>包装元素中缺少一个aligned类。在

看来我得忍受了!在

相关问题 更多 >

    热门问题