form definition dictionary keys must be the field names now; refactoring in the Form
class
This commit is contained in:
parent
7618f6650e
commit
314b287ac4
@ -69,6 +69,29 @@ class FormField:
|
||||
|
||||
|
||||
class Form:
|
||||
|
||||
@staticmethod
|
||||
def fields_from_dict(definition: Dict[str, Optional[dict]]) -> Dict[str, FormField]:
|
||||
"""
|
||||
Takes a dictionary defining form fields and creates `FormFields` objects from it.
|
||||
Every key in `definition` is interpreted as the field's name.
|
||||
The corresponding value can be `None` or a dictionary that can be unpacked into the FormField constructor call
|
||||
alongside the name.
|
||||
The special key `alias` in a field's dictionary is also allowed. If it is present, the corresponding value
|
||||
will be used as the key in the output dictionary; otherwise the field's name is used as the key.
|
||||
The constructed `FormField` objects are the values in the output dictionary.
|
||||
"""
|
||||
field_dict = {}
|
||||
for name, field_def in definition.items():
|
||||
if field_def is None:
|
||||
field_def = {}
|
||||
if isinstance(field_def, dict):
|
||||
alias = field_def.pop('alias', name)
|
||||
field_dict[alias] = FormField(name, **field_def)
|
||||
else:
|
||||
raise TypeError("Field definitions must be either dictionaries or `None`")
|
||||
return field_dict
|
||||
|
||||
def __init__(self, definition: Dict[str, Dict], full_payload: bool = True, url: str = None):
|
||||
"""
|
||||
Creates a form instance from a definition dictionary. Each element in the dictionary must define a field.
|
||||
@ -85,7 +108,7 @@ class Form:
|
||||
url (optional):
|
||||
Can be set in advance to the url that requests using this form's payload should be made to.
|
||||
"""
|
||||
self.fields: Dict[str, FormField] = {alias: FormField(**field_def) for alias, field_def in definition.items()}
|
||||
self.fields: Dict[str, FormField] = self.fields_from_dict(definition)
|
||||
self.full_payload_always: bool = full_payload
|
||||
self.url: Optional[str] = url
|
||||
|
||||
@ -107,8 +130,10 @@ class Form:
|
||||
|
||||
Args:
|
||||
kwargs (optional):
|
||||
Every key must correspond to a key in the internal dictionary of fields;
|
||||
Every key must correspond to an alias or name of a field in the internal dictionary of fields;
|
||||
otherwise that key-value-pair is ignored.
|
||||
If both a field's alias and name are different and both are present as keys in `kwargs`,
|
||||
the alias-key takes precedence.
|
||||
Values will be passed into the payload (if they pass validation).
|
||||
Select fields with predefined options will only allow one of the options to be passed.
|
||||
If `None` is passed as a value, the corresponding field's default value will be used in the payload.
|
||||
@ -117,15 +142,15 @@ class Form:
|
||||
Validated name-value-mapping to be used for HTTP requests from the form's fields.
|
||||
"""
|
||||
payload = {}
|
||||
for key, field in self.fields.items():
|
||||
if key in kwargs.keys():
|
||||
value = kwargs[key]
|
||||
if value is None:
|
||||
payload[field.name] = field.default
|
||||
else:
|
||||
payload[field.name] = field.clean(value)
|
||||
for alias, field in self.fields.items():
|
||||
if alias in kwargs.keys():
|
||||
value = kwargs[alias]
|
||||
payload[field.name] = field.default if value is None else field.clean(value)
|
||||
elif alias != field.name and field.name in kwargs.keys():
|
||||
value = kwargs[field.name]
|
||||
payload[field.name] = field.default if value is None else field.clean(value)
|
||||
elif field.required:
|
||||
raise ValueError(f"`{key}` is a required field, but no argument was passed.")
|
||||
raise ValueError(f"`{alias}` is a required field, but no argument was passed.")
|
||||
elif self.full_payload_always:
|
||||
payload[field.name] = field.default
|
||||
return payload
|
||||
|
Loading…
Reference in New Issue
Block a user