在管理员中动态添加新表单字段

时间:2011-04-19 15:27:10

标签: django django-forms

我正在尝试动态添加新表单字段(我使用此blog post),用于管理界面中使用的表单:

class ServiceRoleAssignmentForm(forms.ModelForm):

    class Meta:
        model = ServiceRoleAssignment

    def __init__(self, *args, **kwargs):
        super(ServiceRoleAssignmentForm, self).__init__(*args, **kwargs)
        self.fields['test'] = forms.CharField(label='test') 


class ServiceRoleAssignmentAdmin(admin.ModelAdmin):
    form = ServiceRoleAssignmentForm

admin.site.register(ServiceRoleAssignment, ServiceRoleAssignmentAdmin)

但是,无论我尝试什么,该字段都不会显示在我的管理表单上!这可能是与管理工作方式有关的问题吗?或者到ModelForm?

感谢您的帮助!

塞巴斯蒂安

PS:我正在使用django 1.3

4 个答案:

答案 0 :(得分:3)

在模板中渲染表单时,字段从fieldsets变量枚举,而不是从字段枚举。当然,您可以在AdminForm中重新定义字段集,但随后验证将失败,因为原始表单类没有此类字段。我可以提出的一个解决方法是静态地在表单定义中定义此字段,然后动态地在表单的 init 方法中重新定义该字段。这是一个例子:

class ServiceRoleAssignmentForm(forms.ModelForm):
    test = forms.Field()

    class Meta:
        model = ServiceRoleAssignment

    def __init__(self, *args, **kwargs):
        super(ServiceRoleAssignmentForm, self).__init__(*args, **kwargs)
        # Here we will redefine our test field.
        self.fields['test'] = forms.CharField(label='test2')

答案 1 :(得分:0)

我实际上有一个同样的问题,我目前正在解决这个问题。 虽然不理想,但我发现了一个适用于我的用例的临时解决方法。它可能对你有用吗?

在我的情况下,我有一个字段的静态名称,所以我只是在我的ModelForm中声明它。正常情况下,我会正常覆盖 init ()以覆盖某些选项。

即:

def statemachine_form(for_model=None):
    """
    Factory function to create a special case form
    """
    class _StateMachineBaseModelForm(forms.ModelForm):
        _sm_action = forms.ChoiceField(choices=[], label="Take Action")

        class Meta:
            model = for_model

        def __init__(self, *args, **kwargs):
            super(_StateMachineBaseModelForm, self).__init__(*args, **kwargs)
            actions = (('', '-----------'),)
            for action in self.instance.sm_state_actions():
                actions += ((action, action),)
            self.fields['_sm_action'] = forms.ChoiceField(choices=actions,
                                                          label="Take Action")
    if for_model: return _StateMachineBaseModelForm

class ContentItemAdmin(admin.ModelAdmin):
    form = statemachine_form(for_model=ContentItem)

正如我之前提到的,这并非完全“动态”,但这暂时对我有用。

我有完全相同的问题,如果我动态添加字段而不先声明它,那么它实际上并不存在。我认为这实际上与ModelForm创建字段的方式有关。

我希望其他人可以给我们更多信息。

答案 2 :(得分:0)

答案 3 :(得分:-2)

尝试在调用super.init之前添加字段:

def __init__(self, *args, **kwargs):
    self.fields['test'] = forms.CharField(label='test') 
    super(ServiceRoleAssignmentForm, self).__init__(*args, **kwargs)