2

I have a form which I want all other forms to inherit from, below is what I have tried but I'm getting an error what suggests the init is not running from the AbstractFormBase class. SchemeForm 'should' inherit all the __init__ arguments before running its own.

Error:

'SchemeForm' object has no attribute 'fields'

Code Updated:

class AbstractFormBase(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-lg-3'
        self.helper.field_class = 'col-lg-8'

class SchemeForm(AbstractFormBase, NgModelFormMixin,):
    def __init__(self, *args, **kwargs):
        super(SchemeForm, self).__init__(*args, **kwargs)
        self.helper.layout = Layout(
            'name',
            'domain',
            'slug',

        )
4
  • Advanced Django Forms Usage pydanny/advanced-django-forms-usage is a valuable doc Commented Jan 10, 2014 at 11:09
  • Well, your form doesn't have any fields; a Django ModelForm requires either a fields or a exclude attribute on the Meta object. Commented Jan 10, 2014 at 11:16
  • Apart from that, your AbstractFormBase doesn't cooperate with any other classes in the inheritance structure. Commented Jan 10, 2014 at 11:18
  • @Martijn Pieters I see I need ModelForm on based form, however I don't want all forms to get the same model. guess I could do this with a function. Commented Jan 10, 2014 at 11:25

3 Answers 3

2

Your AbstractFormBase class doesn't cooperate with the other classes in the inheritance tree. Your SchemeForm class has a specific MRO, a method resolution order. The super() call will only call the next __init__ method in that order, and AbstractFormBase is the next one (followed by NgModelFormMixin and forms.ModelForm).

You would want to pass on the __init__ call to the next class in the MRO by using super() in the AbstractFormBase class:

class AbstractFormBase(object):
    def __init__(self, *args, **kwargs):
        super(AbstractFormBase, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-lg-3'
        self.helper.field_class = 'col-lg-8'

Note that the same applies to NgModelFormMixin, and that form.ModelForm requires that the Meta class has either a fields or a exclude attribute (see selecting the fields to use.)

Sign up to request clarification or add additional context in comments.

Comments

1

Place forms.ModelForm on first place in base classes list:

class SchemeForm(forms.ModelForm, AbstractFormBase, NgModelFormMixin):

and add object as AbstractFormBase base class and add super call in init:

class AbstractFormBase(object):
    def __init__(self, *args, **kwargs):
        super(AbstractFormBase, self).__init__(*args, **kwargs)

4 Comments

still not running :( 'SchemeForm' object has no attribute 'helper'
No, object is not required here, but would be nice.
@MartijnPieters and object is needed here, check your answer)
@ndpu: no, not when the mixin is really used as a mixin. forms.ModelForm inherits (indirectly) from object already.
1

Your Base form needs to inherit from forms.ModelForm

see http://chriskief.com/2013/06/30/django-form-inheritance/

class AbstractFormBase(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-lg-3'
        self.helper.field_class = 'col-lg-8's

    class Meta:
        model = MyModel
        fields = ('field1', 'field2')

class SchemeForm(AbstractFormBase, NgModelFormMixin,):
    def __init__(self, *args, **kwargs):
        super(AbstractFormBase, self).__init__(*args, **kwargs)
            self.helper.layout = Layout(
            'name',
            'domain',
            'slug',
        )

    class Meta(AbstractFormBase.Meta):
        model = MyModel   # Or some other model
        fields = ('field3', 'field4')

3 Comments

I have updated my OP based on your answer but I still get the same error, strange.
Try defining Meta and Fields
Note that your version still should call the ModelForm init! Not calling super(AbstractFormBase, self).__init__(*args, **kwargs) will still break something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.