update docs, add load_all(), tests for load_all, make through field optional

This commit is contained in:
collerek
2021-03-03 19:48:40 +01:00
parent 9ad1528cc0
commit a8ae50276e
56 changed files with 1653 additions and 653 deletions

View File

@ -87,28 +87,6 @@ extraction of ormar model_fields.
`(Tuple[Dict, Dict])`: namespace of the class updated, dict of extracted model_fields
<a name="models.helpers.models.validate_related_names_in_relations"></a>
#### validate\_related\_names\_in\_relations
```python
validate_related_names_in_relations(model_fields: Dict, new_model: Type["Model"]) -> None
```
Performs a validation of relation_names in relation fields.
If multiple fields are leading to the same related model
only one can have empty related_name param
(populated by default as model.name.lower()+'s').
Also related_names have to be unique for given related model.
**Raises**:
- `ModelDefinitionError`: if validation of related_names fail
**Arguments**:
- `model_fields (Dict[str, ormar.Field])`: dictionary of declared ormar model fields
- `new_model (Model class)`:
<a name="models.helpers.models.group_related_list"></a>
#### group\_related\_list
@ -134,3 +112,23 @@ Result dictionary is sorted by length of the values and by key
`(Dict[str, List])`: list converted to dictionary to avoid repetition and group nested models
<a name="models.helpers.models.meta_field_not_set"></a>
#### meta\_field\_not\_set
```python
meta_field_not_set(model: Type["Model"], field_name: str) -> bool
```
Checks if field with given name is already present in model.Meta.
Then check if it's set to something truthful
(in practice meaning not None, as it's non or ormar Field only).
**Arguments**:
- `model (Model class)`: newly constructed model
- `field_name (str)`: name of the ormar field
**Returns**:
`(bool)`: result of the check

View File

@ -5,7 +5,7 @@
#### create\_pydantic\_field
```python
create_pydantic_field(field_name: str, model: Type["Model"], model_field: Type[ManyToManyField]) -> None
create_pydantic_field(field_name: str, model: Type["Model"], model_field: Type["ManyToManyField"]) -> None
```
Registers pydantic field on through model that leads to passed model
@ -42,7 +42,7 @@ field_name. Returns a pydantic field with type of field_name field type.
#### populate\_default\_pydantic\_field\_value
```python
populate_default_pydantic_field_value(ormar_field: Type[BaseField], field_name: str, attrs: dict) -> dict
populate_default_pydantic_field_value(ormar_field: Type["BaseField"], field_name: str, attrs: dict) -> dict
```
Grabs current value of the ormar Field in class namespace
@ -94,7 +94,7 @@ Those annotations are later used by pydantic to construct it's own fields.
#### get\_pydantic\_base\_orm\_config
```python
get_pydantic_base_orm_config() -> Type[BaseConfig]
get_pydantic_base_orm_config() -> Type[pydantic.BaseConfig]
```
Returns empty pydantic Config with orm_mode set to True.

View File

@ -0,0 +1,25 @@
<a name="models.helpers.related_names_validation"></a>
# models.helpers.related\_names\_validation
<a name="models.helpers.related_names_validation.validate_related_names_in_relations"></a>
#### validate\_related\_names\_in\_relations
```python
validate_related_names_in_relations(model_fields: Dict, new_model: Type["Model"]) -> None
```
Performs a validation of relation_names in relation fields.
If multiple fields are leading to the same related model
only one can have empty related_name param
(populated by default as model.name.lower()+'s').
Also related_names have to be unique for given related model.
**Raises**:
- `ModelDefinitionError`: if validation of related_names fail
**Arguments**:
- `model_fields (Dict[str, ormar.Field])`: dictionary of declared ormar model fields
- `new_model (Model class)`:

View File

@ -23,7 +23,7 @@ aliases for proper sql joins.
#### register\_many\_to\_many\_relation\_on\_build
```python
register_many_to_many_relation_on_build(field: Type[ManyToManyField]) -> None
register_many_to_many_relation_on_build(field: Type["ManyToManyField"]) -> None
```
Registers connection between through model and both sides of the m2m relation.
@ -89,11 +89,24 @@ Autogenerated reverse fields also set related_name to the original field name.
- `model_field (relation Field)`: original relation ForeignKey field
<a name="models.helpers.relations.register_through_shortcut_fields"></a>
#### register\_through\_shortcut\_fields
```python
register_through_shortcut_fields(model_field: Type["ManyToManyField"]) -> None
```
Registers m2m relation through shortcut on both ends of the relation.
**Arguments**:
- `model_field (ManyToManyField)`: relation field defined in parent model
<a name="models.helpers.relations.register_relation_in_alias_manager"></a>
#### register\_relation\_in\_alias\_manager
```python
register_relation_in_alias_manager(field: Type[ForeignKeyField]) -> None
register_relation_in_alias_manager(field: Type["ForeignKeyField"]) -> None
```
Registers the relation (and reverse relation) in alias manager.

View File

@ -5,7 +5,7 @@
#### adjust\_through\_many\_to\_many\_model
```python
adjust_through_many_to_many_model(model_field: Type[ManyToManyField]) -> None
adjust_through_many_to_many_model(model_field: Type["ManyToManyField"]) -> None
```
Registers m2m relation on through model.
@ -21,7 +21,7 @@ Sets pydantic fields with child and parent model types.
#### create\_and\_append\_m2m\_fk
```python
create_and_append_m2m_fk(model: Type["Model"], model_field: Type[ManyToManyField], field_name: str) -> None
create_and_append_m2m_fk(model: Type["Model"], model_field: Type["ManyToManyField"], field_name: str) -> None
```
Registers sqlalchemy Column with sqlalchemy.ForeignKey leading to the model.
@ -38,7 +38,7 @@ Newly created field is added to m2m relation through model Meta columns and tabl
#### check\_pk\_column\_validity
```python
check_pk_column_validity(field_name: str, field: BaseField, pkname: Optional[str]) -> Optional[str]
check_pk_column_validity(field_name: str, field: "BaseField", pkname: Optional[str]) -> Optional[str]
```
Receives the field marked as primary key and verifies if the pkname
@ -165,7 +165,7 @@ It populates name, metadata, columns and constraints.
#### update\_column\_definition
```python
update_column_definition(model: Union[Type["Model"], Type["NewBaseModel"]], field: Type[ForeignKeyField]) -> None
update_column_definition(model: Union[Type["Model"], Type["NewBaseModel"]], field: Type["ForeignKeyField"]) -> None
```
Updates a column with a new type column based on updated parameters in FK fields.

View File

@ -0,0 +1,120 @@
<a name="models.helpers.validation"></a>
# models.helpers.validation
<a name="models.helpers.validation.check_if_field_has_choices"></a>
#### check\_if\_field\_has\_choices
```python
check_if_field_has_choices(field: Type[BaseField]) -> bool
```
Checks if given field has choices populated.
A if it has one, a validator for this field needs to be attached.
**Arguments**:
- `field (BaseField)`: ormar field to check
**Returns**:
`(bool)`: result of the check
<a name="models.helpers.validation.convert_choices_if_needed"></a>
#### convert\_choices\_if\_needed
```python
convert_choices_if_needed(field: Type["BaseField"], value: Any) -> Tuple[Any, List]
```
Converts dates to isoformat as fastapi can check this condition in routes
and the fields are not yet parsed.
Converts enums to list of it's values.
Converts uuids to strings.
Converts decimal to float with given scale.
**Arguments**:
- `field (Type[BaseField])`: ormar field to check with choices
- `values (Dict)`: current values of the model to verify
**Returns**:
`(Tuple[Any, List])`: value, choices list
<a name="models.helpers.validation.validate_choices"></a>
#### validate\_choices
```python
validate_choices(field: Type["BaseField"], value: Any) -> None
```
Validates if given value is in provided choices.
**Raises**:
- `ValueError`: If value is not in choices.
**Arguments**:
- `field (Type[BaseField])`: field to validate
- `value (Any)`: value of the field
<a name="models.helpers.validation.choices_validator"></a>
#### choices\_validator
```python
choices_validator(cls: Type["Model"], values: Dict[str, Any]) -> Dict[str, Any]
```
Validator that is attached to pydantic model pre root validators.
Validator checks if field value is in field.choices list.
**Raises**:
- `ValueError`: if field value is outside of allowed choices.
**Arguments**:
- `cls (Model class)`: constructed class
- `values (Dict[str, Any])`: dictionary of field values (pydantic side)
**Returns**:
`(Dict[str, Any])`: values if pass validation, otherwise exception is raised
<a name="models.helpers.validation.construct_modify_schema_function"></a>
#### construct\_modify\_schema\_function
```python
construct_modify_schema_function(fields_with_choices: List) -> SchemaExtraCallable
```
Modifies the schema to include fields with choices validator.
Those fields will be displayed in schema as Enum types with available choices
values listed next to them.
**Arguments**:
- `fields_with_choices (List)`: list of fields with choices validation
**Returns**:
`(Callable)`: callable that will be run by pydantic to modify the schema
<a name="models.helpers.validation.populate_choices_validators"></a>
#### populate\_choices\_validators
```python
populate_choices_validators(model: Type["Model"]) -> None
```
Checks if Model has any fields with choices set.
If yes it adds choices validation into pre root validators.
**Arguments**:
- `model (Model class)`: newly constructed Model