-
-
Notifications
You must be signed in to change notification settings - Fork 397
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
No way to tell that a given form is submitted #402
Comments
This is more broadly important if we want to validate other data sources such as JSON, or PATCH requests, which do not have the same constraints and behaviors as HTML forms. |
We could check if any of the form keys match any of the field names before processing. But this is expensive and unnecessary for the most common case of a single form. It's also incorrect for validation, where "no form data" might legitimately be a validation issue. Alternatively, we could have a |
The most radical change would be to stop considering different data sources differently. Remove I'm not super familiar with PATCH requests (or if there's even a standard), but it wouldn't be a full solution for patching because it wouldn't handle merging lists or nested data, only overwriting it completely. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
It sounds like this issue should be tackled for 3.0. What do you think? |
I would like to get something into 3.0, but as I've said above I don't know what that would look like. I don't think there's going to be a 100% satisfying solution to this. |
We need to come up with a policy for data processing and apply it consistently. We need to keep in mind that WTForms is intended first for processing HTML form data, and account for the fact that HTML form data is ambiguous in some cases such as boolean, multi-select, and file fields. There are multiple types of data:
There are multiple places where processing happens:
This post initially started as me collecting all the discussions once again, but turned into a big dump of my current thoughts on behavior of the entire processing stack. The amount of information here might make the situation look worse than it is. WTForms is already fairly consistent and works, but there's a lot of little inconsistencies and ambiguities that can be addressed. |
Further down the line, a solution to ambiguous fields could be to render a hidden input with some sentinel value in order to force a submitted form to send a value for the field. For example a boolean field could render a hidden input with "value=unchecked" and then a checkbox with "value=true". If the list of values only contains the sentinel, it is false, otherwise it is true. If the name is not in the form data at all, we now know it was not sent and can safely assume the default. Similar schemes can be used for other field types. I'm not sure exactly how this would work, fields right now only render one input, and hidden fields are usually rendered in one block with |
@tomchristie Any insight from TypeSystem on handling the ambiguity of missing HTML form data? I couldn't find a discussion of that in its docs. |
Erm, I guess useful points are...
Don't know if that's any help. 🤷♂️ |
Haha, sorry to drag you into this without warning, I just remembered you had worked on a form library recently, thanks for answering 😅 |
(I'm unsure this is useful, but, as WTForms user, this is the way I expect WTForms would behave:
|
For a start it should be possible to use the name and id of a form to be able to work around this missing feature with e.g. some javascript solution that calls the submit button of another form and handles the necessary data. See also the lengthy discussion in https://stackoverflow.com/questions/18290142/multiple-forms-in-a-single-page-using-flask-and-wtforms |
Related to at least #119, #242, #267, #280, #291, #355, #401
We do
if formdata is not None
before callingprocess_formdata
on each field in a form. This broke the rather common case where users were passingrequest.form
to a form even if the method wasn't POST becauserequest.form
isn'tNone
. Previously we checkedbool(formdata)
, which handled this case but caused processing to behave inconsistently depending on what was submitted.Flask-WTF somewhat handles this by only passing
request.form
if the method is actually a submit method (POST, PUT, DELETE).None of the approaches are really correct. Maybe you have a client that always sends some extra data (for example, an auth key). Or you have two forms on the same page, whichever was not submitted will still see the same non-empty form data as the one that was submitted.
Most built-in fields mask this issue because they only change
data
(which is set from the default / object data first) ifformdata.getlist('name')
is not empty. However,StringField
will setdata = ''
if nothing was submitted (which #355 changes). AndSelectMultipleField
andMultipleFileField
will overwrite with an empty list because there's no way to distinguish "selected zero values" with "didn't send data" (BooleanField
has a similar problem.)This can also cause weird issues during validation with
InputRequired
. If there are two forms, and you do something likeif f1.validate(): ... elif f2.validate(): ...
, andf1
was not submitted, it will show a "input required" error even if a default value was being displayed, which is confusing.I'm not sure what the solution is here, but am open to discussion. We can break things, I don't care about backwards compatibility for 3.0.
CC @lepture @alanhamlett
The text was updated successfully, but these errors were encountered: