#25408: Pass additional arguments to BaseForm.__init__ from 
BaseModelForm.__init__
--------------------------------------+---------------------------------
     Reporter:  MoritzS               |      Owner:  nobody
         Type:  Cleanup/optimization  |     Status:  new
    Component:  Forms                 |    Version:  master
     Severity:  Normal                |   Keywords:  form modelform args
 Triage Stage:  Unreviewed            |  Has patch:  0
Easy pickings:  0                     |      UI/UX:  0
--------------------------------------+---------------------------------
 Consider the following module "myapp.forms":

 {{{
 class CustomForm(BaseForm):
     def __init__(self, **kwargs):
         self.custom_kwarg = kwargs.pop('custom_kwarg', 'not available')

     def is_valid(self):
         if self.custom_kwarg:
             return True
         else:
             return super().is_valid()


 class CustomModelForm(ModelForm, CustomForm):
     pass
 }}}
 This module adds additional functionality to forms by adding a new keyword
 argument. If you want to use the new feature on a ModelForm too, that
 won't work because `BaseModelForm.__init__()` doesn't capture additional
 arguments.
 You can work around that like follows:

 {{{
 class CustomFormArg(BaseForm):
     def __init__(self, **kwargs):
         self.custom_kwarg = kwargs.pop('custom_kwarg', False)


 class CustomFormMethod(BaseForm):
     def is_valid(self):
         if self.custom_kwarg:
             return True
         else:
             return super().is_valid()


 class CustomForm(CustomFormArg, CustomFormMethod):
     pass


 class CustomModelForm(CustomFormArg, ModelForm, CustomFormMethod):
     pass
 }}}
 But I think it makes more sense to let BaseModelForm pass the arguments to
 the super() call. Maybe it would also be better if BaseModelForm only took
 `**kwargs` instead of listing all arguments again.

 Note: In some cases this can be fixed by reversing the bases of
 CustomModelForm:
 {{{
 class CustomModelForm(CustomForm, ModelForm):
     pass
 }}}
 However then the mro would be:
 {{{
 myapp.forms.CustomModelForm
 myapp.forms.CustomForm
 django.forms.models.ModelForm
 django.forms.models.BaseModelForm
 django.forms.forms.BaseForm
 object
 }}}
 instead of the more correct
 {{{
 myapp.forms.CustomModelForm
 django.forms.models.ModelForm
 django.forms.models.BaseModelForm
 myapp.forms.CustomForm
 django.forms.forms.BaseForm
 object
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25408>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.e0d583d9373f3500a3f32e4aa147d43e%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to