The problem is that if you use your idiom, data and files are None when the class is instantiated. This is currently a sign that the form has no data attached. Currently, if you want to massage input data before cleaning, you do it using either form of of overriding __init__ as you describe. But if you call "form = MyForm(); form.set_data(request.POST, request.FILES)" then code in __init__ runs while data and files are None, and doesn't have a chance to run when you set them to proper values.
I'm not sure that this is actually such a concern. It is backwards compatible, in the sense that any Django site that ran before the change will continue to run after the change. It would be incompatible to start using set_data instead of the constructor in Django core when it instantiates a user-provided form class (maybe the admin does this? I can't remember). Regardless, it adds complexity to any form subclasses, which have to handle additional entry points for form data, and understand the way the constructor calls the set_data method (for example, your patch calls set_data before setting any of the other fields typically present on a form, so subclasses may see unexpected things if they override it). So I'm -0 due to the additional complexity for something which is already possible and has a widely used idiom, even if it is more verbose. Best, Alex Ogier On Thu, Jan 31, 2013 at 12:13 PM, Byron Ruth <[email protected]> wrote: > I don't want to belabor our difference in understanding/opinion, but there > are two ways to extend __init__. Processing before super is called, and > processing after super is called: > > # Common pre-processing.. > class MyForm(forms.Form): > def __init__(self, request, *args, **kwargs): > # Use downstream somewhere.. > self.request = request > super(MyForm, self).__init__(*args, **kwargs) > > # Common post-processing.. > class MyForm(forms.Form): > def __init__(self, *args, **kwargs): > super(MyForm, self).__init__(*args, **kwargs) > # tweak various field properties.. > > In either case, the `data` and `files` attributes are set as they were > before which means they are still available just like before. Am I missing > something? Do you or Shai have a real example that would correct > understanding? > > On Jan 31, 2013, at 11:56 AM, Alex Ogier <[email protected]> wrote: > > Byron, I think Shai is suggesting that a user's form class may do extra > processing in __init__ on the data and files fields. If someone starts > using the new pattern in their views, it will break those classes because > they expect the initializer to be called with valid data when there is any. > Your new method will bypass their customizations. > > Best, > Alex Ogier > > > On Thu, Jan 31, 2013 at 8:51 AM, Byron Ruth <[email protected]> wrote: > >> I don't understand your argument regarding overriding `__init__`. Nothing >> has changed in __init__, the logic for setting `data` and `files` is simply >> moved to a method. You _can_ still pass `request.POST` and `request.FILES` >> into the constructor. If a user extends __init__ (I do it all the time), >> you still need (are expected) to call `super` to _finish_ initialization. >> >> >> On Thursday, January 31, 2013 1:08:52 AM UTC-5, Shai Berger wrote: >>> >>> On Thursday 31 January 2013, Byron Ruth wrote: >>> > Here is the ticket: >>> > https://code.djangoproject.**com/ticket/19668<https://code.djangoproject.com/ticket/19668>and >>> > the >>> > pull request >>> > https://github.com/django/**django/pull/674<https://github.com/django/django/pull/674> >>> > >>> > One user commented on the ticket raising a concern that it could >>> possibly >>> > be misused if the data is set after it had been used. It is certainly >>> a >>> > valid concern, however it should be made clear in the docs when to use >>> it >>> > and/or raise an exception if `is_valid` has already been called. >>> > >>> > Thoughts? >>> >>> While this is backwards-compatible per se, using it in views is >>> generally not >>> backwards-compatible with user form classes (you can't tell what they do >>> in >>> their initializers); thus, generic views (and also some not-generic >>> views) are >>> forced to keep using the "old way" unless the (user) form code is >>> altered. >>> Which means, you'll have two ways to do the same thing (in views), >>> without a >>> clear preference between them. >>> >>> So if you want this judged as a backwards-compatible change, I'm -1. >>> >>> As a non-backwards-compatible change, I'd like it, but I don't think >>> it's >>> worth the disruption, so I'm -0. >>> >>> Either way, I'm not a core dev. >>> >>> Shai. >>> >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django developers" 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]. >> Visit this group at >> http://groups.google.com/group/django-developers?hl=en. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >> > > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" 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]. > Visit this group at http://groups.google.com/group/django-developers?hl=en > . > For more options, visit https://groups.google.com/groups/opt_out. > > > > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" 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]. > Visit this group at http://groups.google.com/group/django-developers?hl=en > . > For more options, visit https://groups.google.com/groups/opt_out. > > > -- You received this message because you are subscribed to the Google Groups "Django developers" 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]. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
