Django ModelForm inheritance and Meta inheritance

ぐ巨炮叔叔 提交于 2020-12-30 07:38:48

问题


I have this ModelForm:

class Event(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(Event, self).__init__(*args, **kwargs)
        ##Here make some changes such as:
        self.helper = FormHelper()
        self.helper.form_method = 'POST'
        ##Many settings here which **i don't want to rewrite in 10 child classes**

    class Meta:
        model = Event
        exclude = something...
        widgets = some settings here also.

And this child ModelForm:

class UpgradedEvent(Event):

    def __init__(self, *args, **kwargs):
        super(UpgradedEvent,self).__init__(*args,**kwargs)

    class Meta(Event.Meta):
        model = UpgradedEvent

UpgradedEvent is a child of Event model but has some extra fields. How can i inherit all the settings from the Event FORM into UpgradedEvent FORM?

When running the above code, it renders the Event form. Is there a way to inherit only the settings inside __init__ ?

EDIT

Check out the answer, it works great but keep in mind: you need to create another instance of FormHelper in your child class, otherwise it won't work. So child class should look something like:

class UpgradedEvent(Event):

    def __init__(self, *args, **kwargs):
        super(UpgradedEvent,self).__init__(*args,**kwargs)
        self.helper = FormHelper()

    class Meta(Event.Meta):
        model = UpgradedEvent

回答1:


Create FormWithSettings which will hold common settings for you form classes and inherit it

class FormWithSettings(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(FormWithSettings, self).__init__(*args, **kwargs)
        ##Here make some changes such as:
        self.helper = FormHelper()
        self.helper.form_method = 'POST'
        ##Many settings here which **i don't want to rewrite in 10 child classes**

    class Meta:
        exclude = something...
        widgets = some settings here also.

class EventForm(FormWithSettings):

    def __init__(self, *args, **kwargs):
        super(EventForm, self).__init__(*args,**kwargs)

    class Meta(FormWithSettings.Meta):
        model = Event

class UpgradedEventForm(FormWithSettings):

    def __init__(self, *args, **kwargs):
        super(UpgradedEventForm, self).__init__(*args,**kwargs)

    class Meta(FormWithSettings.Meta):
        model = UpgradedEvent



回答2:


You can obtain the fields the Meta above, and extend the lists, etc.:

class UpgradedEventForm(EventForm):

    def __init__(self, *args, **kwargs):
        super(UpgradedEventForm,self).__init__(*args,**kwargs)
        # some extra settings
        # ...
        # for example
        self.fields['extra_field'].initial = 'initial value of extra field'

    class Meta(EventForm.Meta):
        model = UpgradedEvent
        exclude = EventForm.Meta.exclude + ['extra_exclude1', 'extra_exclude2']
        fields = EventForm.Meta.fields + ['extra_field']

So by using inheritance, we can add extra procedures to the __init__ function by performing some extra actions after the super(UpgradedEventForm, self) call, and wwe can access the attributes of our parent, and extend these.

Note that you better name your forms with a Form suffix, since now your models clash with your forms. As a result, your Form seems to have as model a reference to the Form itself. By using proper "nomenclature", you avoid a lot of mistakes.



来源:https://stackoverflow.com/questions/50487334/django-modelform-inheritance-and-meta-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!