Hello,
Am 05.03.2016 um 02:57 schrieb Curtis Maloney:
> Well, Widgets and Fields are involved in determining how to extract data from
> the submitted dict... but they don't actually "parse" the http form data --
> Django does that much further down the stack in the HttpRequest object.
>
>
> As mentioned above, Forms don't handle this parsing. You can pass _any_
> dict-like for them to validate. In fact, I (and many others) have used this for
> a simple and effective way to import csv files, in combination with stdlib's
> csv.DictReader.
>
> I also frequently use Forms for validating JSON data...
You are right there, I guess "parsing" is the wrong word for what I mean.
The thing is that for "simple" Widgets like TextInput getting the value out of
the data dict is as simple as data.get(add_prefix(name)) so it is reasonably
easy to just pass in a normal dict as data instead of a request.POST because you
already know how the widget will fetch its data.
However it gets way more complicated with more complex Widgets. Say you have a
DateInput widget that uses three HTML input tags that let you enter the year,
month, and day respectively. If you were to replace request.POST with your own
dict now you would have to account for how this widget layouts its data, i.e.
you would have to do something like:
my_data_dict = {'prefix-thedate-year': 2016, 'prefix-thedate-month': 3,
'prefix-thedate-day': 5}
Even though the "thedate" is only one logical value you would have to "split" it
to get the form to "parse" it correctly. Also you have to know in advance how
your DateWidget works and have to change your code every time you use another
new (complex) widget.
I believe it should be possible to provide input data in whatever format without
needing to know how the widget expects the data.
Another thing I consider part of "parsing" is how "initial" data is handled.
Let's now pretend we know how to correctly replace request.POST with our own
dict regardless of the used widgets. Let's also disregard for now that the
inital dict's format is actually not like the data dict's because it already
contains *logical* values, i.e. stripped off prefix and only one value for each
logical field.
So now we can construct an "inital" dict just like we did for the data dict.
However the thing about the inital data is that Django already has an opinion on
what it is and how it should be handled.
I had a use case were I needed an additional layer of "initial" data that was
called something like "database initial". So I then had three types of data: the
actual "data" dict, "user initial" (similar to what Django considers to be
initial) and "database initial".
Because the concept of "initial" data is ingrained so deeply in the Form class I
had to customize a large part of the Form class internals and even BoundField.
That are the reasons why I believe "parsing", or better "sourcing" as you called
it, should be customizable.
> I feel the current validation pattern is very powerful and flexible, and don't
> see much need to alter it.
I feel the same way. For this reason I want to keep the way one specifies
validators exactly the same as it is now, i.e. by specifying Field instances
declaratively and being able to write clean() and clean_*() methods.
>> - DataProvider:
>> Implements the "parsing and providing data" component. It
>> has only one method "get_value(name)" that must be
>> overwritten by subclasses and returns the data for a given
>> field name.
>
> So that would be a "get_field_value"?
Exactly.
> This scale of backwards incompatibility might scare off a lot of people from
> supporting this project. So be sure to provide (a) an easy migration path,
> and/or (b) a clear backward compatibility layer.
Yes, I want to emphasize again that this is an important part of my proposal.
> I'd be happy to further develop these ideas [and code] with you if you like.
I actually already have a bit of code as a proof of concept, I think I'll open a
branch on my Django fork or even a PR.
However I moved around quite a lot of code so I suspect it will be a bit messy
to review.
Moritz