开发者

adding new form fields dynamically in admin

I am trying to add dynamically new form fields (I used this blog post), for a form used in admin interface :

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)

However, no matter what I try, the field doesn't appear on my admin form ! Could it be a problem related to the way admin works ? Or to ModelForm ?

Thank for any help !

Sébastien

PS : I am using django 1.3


When rendering your form in template, fields enumerating from fieldsets variable, not from fields. Sure you can redefine fieldsets in your AdminForm, but then validations will fail as original form class doesn't have such field. One workaround I can propose is to define this field in form definition statically and then redefine that field in form's init method dynamically. Here is an example:

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')


I actually have a the same issue which I'm working through at the moment. While not ideal, I have found a temporary workaround that works for my use case. It might be of use to you?

In my case I have a static name for the field, so I just declared it in my ModelForm. as normal, I then override the init() as normal to override some options.

ie:

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)

Now as I mentioned before, this is not entirely 'dynamic', but this will do for me for the time being.

I have the exact same problem that, if I add the field dynamically, without declaring it first, then it doesn't actually exist. I think this does in fact have something to do with the way that ModelForm creates the fields.

I'm hoping someone else can give us some more info.


Django - Overriding get_form to customize admin forms based on request


Try to add the field before calling the super.init:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜