-
-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Field data overhaul #662
Comments
I agree. Either the form was submitted and only that data is processed, or the form is setting up defaults and only that data is processed.
I agree, but I think there's some related issues to address as well.
I'll have to see what this looks like, but it sounds like a decent goal. Is the idea for every field to have a
I'm not sure if this distinction is good. There is a similar disconnect in Click where input was mostly assumed to be all strings (from the command line), and types and defaults were handling already converted values inconsistently. There, we're moving towards having processing always work with strings or objects the same way, regardless of the source and type. As to the specific
I agree with this, but it seems to go against your previous suggestion. Maybe I'm misunderstanding.
I think the current behavior of preferring |
Yes
Actually both points are related. In the latter I meant we should write some tests that pass already coerced data to process_data.
Right. To reformulate: I suggest avoiding returning raw data in |
I think there are some inconsistencies in the way data is handled by fields:
How things works now
Here is a small reminder on how inputs are handled in forms and fields.
input
There are several ways to put data into a field:
Form.process()
formdata
argument);Form.process()
obj
argument);Form.process()
data
argument);Field
default
argument).process
Then in
Field.process()
:Field.process_formdata()
processes the form data. The input in always a list of strings. The form data is stored inField.raw_data
, then it may be coerced in a convenient python type, and is finally stored the result inField.data
;Field.process_data()
processes the object data value, or the data dict value, or the field default value (in that order). The input can have any type. The form data is stored inField.object_data
, then it may be coerced in a convenient python type, and is finally stored the result inField.data
.filters
are successively applied, and may transformField.data
.process_formdata()
andprocess_data()
may find errors and add them intoField.process_errors
validate
Validation consists in:
Field.pre_validate()
;Field.post_validate()
.Generally
pre_validate()
,post_validate()
and the validators handleField.data
, that is python data. In addition to the process errorsvalidate()
adds the validation errors intoField.errors
.output
Field._value()
returns a value to display for the widgets. Generally it transformsField.data
in a htmlized form, but sometimes it takes shortcuts by returning the field formdata input (inField.raw_data
):https://github.com/wtforms/wtforms/blob/9cc7c7f4d32c8e69c67460e8b8b2aa5ed411da2e/src/wtforms/fields/core.py#L707-L712
Problems
both
process_formdata()
andprocess_data()
are executedIf the field has some
formdata
, thenprocess_formdata()
will overwriteself.data
if it has been previously set byprocess_data()
. It seems useless to executeprocess_data()
at all then.https://github.com/wtforms/wtforms/blob/9cc7c7f4d32c8e69c67460e8b8b2aa5ed411da2e/src/wtforms/fields/core.py#L342-L356
process_data()
ifformdata is not None
.validation is always attempted
As discussed in #61, #360, #435, even if
Field.process_data()
orField.process_formdata()
raise aValueError
, and thenField.validate()
is called, then validation on that field will be attempted.Field.validate()
skips and always returnFalse
ifField.process_error
is not empty.validators handle one single value
In 2015, among the goals for v3 #154 tells us:
Some fields have multiple data (
SelectMultipleField
orMultipleFileField
), most field have one unique value, but I cannot think of any field without value. Even submit buttons have a value.Validators usually expect
Field.data
to be a single value, and sometimes (#442) that can cause issues. I can see two way to solve this:The latter implementation would not concern a lot of builtin validators, but might be useful for custom user-written validators.
should
process_formdata()
andprocess_data()
be flexible with the input?As mentioned in #659, an
IntegerField
will silently accept and cast a float input. If the float is coming from the form, I think this should be refused byprocess_formdata()
. But what if the float is coming from objdata? It feels pretty convenient to have silent casts in that situation.process_formdata()
won't cast anything silently, butprocess_data()
will do.python input types are not always handled correctly
I said earlier that the input for process_data can have any type. However there are some cases that break those principles (as discussed in #609). For example,
DateTimeField
cannot validatedatetime.datetime
input data:Field._value() makes false assumptions
Field._value
directly returning the input formdata (when there is one) assumes that the HTML data input and the HTML data output will always be the same. But as theprocess
step may transform the data, for example with filters, this assumption won't alway be true, and the data returned will be incorrect.Field._value()
, unless there has been errors processing the field.The text was updated successfully, but these errors were encountered: