When a Pydantic BaseModel is used as a Form() parameter, fields that
were absent from the submission or submitted as blank strings ("") were
being pre-filled with their default values before model construction.
Pydantic then treated those pre-filled defaults as explicitly-set values,
making model_fields_set incorrect and preventing model validators from
distinguishing unset fields from fields set to their default.
Two cases needed fixing:
1. Absent fields - the field key is not in the form data at all
(e.g. an unchecked HTML checkbox, which browsers omit entirely).
2. Blank string fields - the field key is present but with value ""
(e.g. a cleared text input, which browsers send as key=).
Fix: add form_input=True parameter to _get_multidict_value. When set,
both absent and blank-string values return None rather than the field
default. _extract_form_body now calls _get_multidict_value(form_input=True)
so neither case gets pre-populated into the values dict. Pydantic then
applies defaults through its own mechanism, which correctly leaves those
fields out of model_fields_set.
Required fields are unaffected: Pydantic still raises a validation error
when a required field is absent from the submitted data.
Closes#13399
Co-authored-by: sneakers-the-rat <[email protected]>