【问题标题】:Django ModelForm inheritance and Meta inheritanceDjango ModelForm 继承和 Meta 继承
【发布时间】:2018-05-23 11:32:17
【问题描述】:

我有这个 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.

还有这个子 ModelForm:

class UpgradedEvent(Event):

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

    class Meta(Event.Meta):
        model = UpgradedEvent

UpgradedEventEvent model 的子级,但有一些额外的字段。 如何将Event FORM 中的所有设置继承到UpgradedEvent FORM 中?

运行上述代码时,它会呈现Event 表单。有没有办法只继承__init__ 中的设置?

编辑

查看答案,效果很好,但请记住: 您需要在您的子类中创建另一个 FormHelper 实例,否则它将不起作用。所以子类应该是这样的:

class UpgradedEvent(Event):

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

    class Meta(Event.Meta):
        model = UpgradedEvent

【问题讨论】:

    标签: python django inheritance django-forms


    【解决方案1】:

    可以获取上面Meta的字段,扩展列表等:

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

    因此,通过使用继承,我们可以通过在super(UpgradedEventForm, self) 调用之后执行一些额外的操作来为__init__ 函数添加额外的过程,并且我们可以访问父级的属性并扩展这些属性。

    请注意,您最好使用Form 后缀命名您的表单,因为现在您的模型与您的表单发生冲突。因此,您的 Form 似乎具有对 Form 本身的引用作为模型。通过使用正确的“命名法”,您可以避免很多错误。

    【讨论】:

      【解决方案2】:

      创建FormWithSettings,它将为您的表单类保存通用设置并继承它

      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
      

      【讨论】:

      • 问题是我在__init__ 中有很多设置,我不想在Event 表单的10 个子类中复制粘贴。
      • 我确实尝试过实现这个想法,但我完全不知道为什么它不起作用。如果我继承元数据,它可以工作,如果我尝试UpgradedEventForm(FormWithSettings),我会丢失升级类的额外字段,我完全不知道为什么,因为如果我只是继承元数据,它们就可以正常工作。
      • @MikeVlad 请发布您的实际代码,以及您对它的期望
      • @我想通了,我会编辑问题。那是我必须创建另一个 FormHelper 实例 - Crispy Forms
      • 我不得不重启 django 服务器才能看到变化
      猜你喜欢
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多