fix isnull typo and formatting
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
p38venv
|
p38venv
|
||||||
alembic
|
alembic
|
||||||
alembic.ini
|
alembic.ini
|
||||||
|
build
|
||||||
.idea
|
.idea
|
||||||
.pytest_cache
|
.pytest_cache
|
||||||
.mypy_cache
|
.mypy_cache
|
||||||
|
|||||||
@ -20,8 +20,7 @@ to pydantic field types like ConstrainedStr
|
|||||||
#### is\_valid\_uni\_relation
|
#### is\_valid\_uni\_relation
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| is_valid_uni_relation() -> bool
|
||||||
| is_valid_uni_relation(cls) -> bool
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if field is a relation definition but only for ForeignKey relation,
|
Checks if field is a relation definition but only for ForeignKey relation,
|
||||||
@ -40,8 +39,7 @@ Model columns only.
|
|||||||
#### get\_alias
|
#### get\_alias
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_alias() -> str
|
||||||
| get_alias(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Used to translate Model column names to database column names during db queries.
|
Used to translate Model column names to database column names during db queries.
|
||||||
@ -51,75 +49,26 @@ Used to translate Model column names to database column names during db queries.
|
|||||||
`(str)`: returns custom database column name if defined by user,
|
`(str)`: returns custom database column name if defined by user,
|
||||||
otherwise field name in ormar/pydantic
|
otherwise field name in ormar/pydantic
|
||||||
|
|
||||||
<a name="fields.base.BaseField.is_valid_field_info_field"></a>
|
<a name="fields.base.BaseField.get_pydantic_default"></a>
|
||||||
#### is\_valid\_field\_info\_field
|
#### get\_pydantic\_default
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_pydantic_default() -> Dict
|
||||||
| is_valid_field_info_field(cls, field_name: str) -> bool
|
|
||||||
```
|
|
||||||
|
|
||||||
Checks if field belongs to pydantic FieldInfo
|
|
||||||
- used during setting default pydantic values.
|
|
||||||
Excludes defaults and alias as they are populated separately
|
|
||||||
(defaults) or not at all (alias)
|
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `field_name (str)`: field name of BaseFIeld
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(bool)`: True if field is present on pydantic.FieldInfo
|
|
||||||
|
|
||||||
<a name="fields.base.BaseField.get_base_pydantic_field_info"></a>
|
|
||||||
#### get\_base\_pydantic\_field\_info
|
|
||||||
|
|
||||||
```python
|
|
||||||
| @classmethod
|
|
||||||
| get_base_pydantic_field_info(cls, allow_null: bool) -> FieldInfo
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Generates base pydantic.FieldInfo with only default and optionally
|
Generates base pydantic.FieldInfo with only default and optionally
|
||||||
required to fix pydantic Json field being set to required=False.
|
required to fix pydantic Json field being set to required=False.
|
||||||
Used in an ormar Model Metaclass.
|
Used in an ormar Model Metaclass.
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `allow_null (bool)`: flag if the default value can be None
|
|
||||||
or if it should be populated by pydantic Undefined
|
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
`(pydantic.FieldInfo)`: instance of base pydantic.FieldInfo
|
`(pydantic.FieldInfo)`: instance of base pydantic.FieldInfo
|
||||||
|
|
||||||
<a name="fields.base.BaseField.convert_to_pydantic_field_info"></a>
|
|
||||||
#### convert\_to\_pydantic\_field\_info
|
|
||||||
|
|
||||||
```python
|
|
||||||
| @classmethod
|
|
||||||
| convert_to_pydantic_field_info(cls, allow_null: bool = False) -> FieldInfo
|
|
||||||
```
|
|
||||||
|
|
||||||
Converts a BaseField into pydantic.FieldInfo
|
|
||||||
that is later easily processed by pydantic.
|
|
||||||
Used in an ormar Model Metaclass.
|
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `allow_null (bool)`: flag if the default value can be None
|
|
||||||
or if it should be populated by pydantic Undefined
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(pydantic.FieldInfo)`: actual instance of pydantic.FieldInfo with all needed fields populated
|
|
||||||
|
|
||||||
<a name="fields.base.BaseField.default_value"></a>
|
<a name="fields.base.BaseField.default_value"></a>
|
||||||
#### default\_value
|
#### default\_value
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| default_value(use_server: bool = False) -> Optional[Dict]
|
||||||
| default_value(cls, use_server: bool = False) -> Optional[FieldInfo]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns a FieldInfo instance with populated default
|
Returns a FieldInfo instance with populated default
|
||||||
@ -145,8 +94,7 @@ which is returning a FieldInfo instance
|
|||||||
#### get\_default
|
#### get\_default
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_default(use_server: bool = False) -> Any
|
||||||
| get_default(cls, use_server: bool = False) -> Any
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Return default value for a field.
|
Return default value for a field.
|
||||||
@ -166,8 +114,7 @@ treated as default value, default False
|
|||||||
#### has\_default
|
#### has\_default
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| has_default(use_server: bool = True) -> bool
|
||||||
| has_default(cls, use_server: bool = True) -> bool
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if the field has default value set.
|
Checks if the field has default value set.
|
||||||
@ -185,8 +132,7 @@ treated as default value, default False
|
|||||||
#### is\_auto\_primary\_key
|
#### is\_auto\_primary\_key
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| is_auto_primary_key() -> bool
|
||||||
| is_auto_primary_key(cls) -> bool
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if field is first a primary key and if it,
|
Checks if field is first a primary key and if it,
|
||||||
@ -201,8 +147,7 @@ Autoincrement primary_key is nullable/optional.
|
|||||||
#### construct\_constraints
|
#### construct\_constraints
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| construct_constraints() -> List
|
||||||
| construct_constraints(cls) -> List
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Converts list of ormar constraints into sqlalchemy ForeignKeys.
|
Converts list of ormar constraints into sqlalchemy ForeignKeys.
|
||||||
@ -217,8 +162,7 @@ And we need a new ForeignKey for subclasses of current model
|
|||||||
#### get\_column
|
#### get\_column
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_column(name: str) -> sqlalchemy.Column
|
||||||
| get_column(cls, name: str) -> sqlalchemy.Column
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns definition of sqlalchemy.Column used in creation of sqlalchemy.Table.
|
Returns definition of sqlalchemy.Column used in creation of sqlalchemy.Table.
|
||||||
@ -233,12 +177,28 @@ primary_key, index, unique, nullable, default and server_default.
|
|||||||
|
|
||||||
`(sqlalchemy.Column)`: actual definition of the database column as sqlalchemy requires.
|
`(sqlalchemy.Column)`: actual definition of the database column as sqlalchemy requires.
|
||||||
|
|
||||||
|
<a name="fields.base.BaseField._get_encrypted_column"></a>
|
||||||
|
#### \_get\_encrypted\_column
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _get_encrypted_column(name: str) -> sqlalchemy.Column
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns EncryptedString column type instead of actual column.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `name (str)`: column name
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(sqlalchemy.Column)`: newly defined column
|
||||||
|
|
||||||
<a name="fields.base.BaseField.expand_relationship"></a>
|
<a name="fields.base.BaseField.expand_relationship"></a>
|
||||||
#### expand\_relationship
|
#### expand\_relationship
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| expand_relationship(value: Any, child: Union["Model", "NewBaseModel"], to_register: bool = True) -> Any
|
||||||
| expand_relationship(cls, value: Any, child: Union["Model", "NewBaseModel"], to_register: bool = True) -> Any
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Function overwritten for relations, in basic field the value is returned as is.
|
Function overwritten for relations, in basic field the value is returned as is.
|
||||||
@ -261,8 +221,7 @@ dict (from Model) or actual instance/list of a "Model".
|
|||||||
#### set\_self\_reference\_flag
|
#### set\_self\_reference\_flag
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| set_self_reference_flag() -> None
|
||||||
| set_self_reference_flag(cls) -> None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Sets `self_reference` to True if field to and owner are same model.
|
Sets `self_reference` to True if field to and owner are same model.
|
||||||
@ -275,8 +234,7 @@ Sets `self_reference` to True if field to and owner are same model.
|
|||||||
#### has\_unresolved\_forward\_refs
|
#### has\_unresolved\_forward\_refs
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| has_unresolved_forward_refs() -> bool
|
||||||
| has_unresolved_forward_refs(cls) -> bool
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Verifies if the filed has any ForwardRefs that require updating before the
|
Verifies if the filed has any ForwardRefs that require updating before the
|
||||||
@ -290,8 +248,7 @@ model can be used.
|
|||||||
#### evaluate\_forward\_ref
|
#### evaluate\_forward\_ref
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| evaluate_forward_ref(globalns: Any, localns: Any) -> None
|
||||||
| evaluate_forward_ref(cls, globalns: Any, localns: Any) -> None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Evaluates the ForwardRef to actual Field based on global and local namespaces
|
Evaluates the ForwardRef to actual Field based on global and local namespaces
|
||||||
@ -309,8 +266,7 @@ Evaluates the ForwardRef to actual Field based on global and local namespaces
|
|||||||
#### get\_related\_name
|
#### get\_related\_name
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_related_name() -> str
|
||||||
| get_related_name(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name to use for reverse relation.
|
Returns name to use for reverse relation.
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### create\_dummy\_instance
|
#### create\_dummy\_instance
|
||||||
|
|
||||||
```python
|
```python
|
||||||
create_dummy_instance(fk: Type["Model"], pk: Any = None) -> "Model"
|
create_dummy_instance(fk: Type["T"], pk: Any = None) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Ormar never returns you a raw data.
|
Ormar never returns you a raw data.
|
||||||
@ -31,7 +31,7 @@ If the nested related Models are required they are set with -1 as pk value.
|
|||||||
#### create\_dummy\_model
|
#### create\_dummy\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
create_dummy_model(base_model: Type["Model"], pk_field: Type[Union[BaseField, "ForeignKeyField", "ManyToManyField"]]) -> Type["BaseModel"]
|
create_dummy_model(base_model: Type["T"], pk_field: Union[BaseField, "ForeignKeyField", "ManyToManyField"]) -> Type["BaseModel"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Used to construct a dummy pydantic model for type hints and pydantic validation.
|
Used to construct a dummy pydantic model for type hints and pydantic validation.
|
||||||
@ -40,7 +40,7 @@ Populates only pk field and set it to desired type.
|
|||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `base_model (Model class)`: class of target dummy model
|
- `base_model (Model class)`: class of target dummy model
|
||||||
- `pk_field (Type[Union[BaseField, "ForeignKeyField", "ManyToManyField"]])`: ormar Field to be set on pydantic Model
|
- `pk_field (Union[BaseField, "ForeignKeyField", "ManyToManyField"])`: ormar Field to be set on pydantic Model
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ Populates only pk field and set it to desired type.
|
|||||||
#### populate\_fk\_params\_based\_on\_to\_model
|
#### populate\_fk\_params\_based\_on\_to\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
populate_fk_params_based_on_to_model(to: Type["Model"], nullable: bool, onupdate: str = None, ondelete: str = None) -> Tuple[Any, List, Any]
|
populate_fk_params_based_on_to_model(to: Type["T"], nullable: bool, onupdate: str = None, ondelete: str = None) -> Tuple[Any, List, Any]
|
||||||
```
|
```
|
||||||
|
|
||||||
Based on target to model to which relation leads to populates the type of the
|
Based on target to model to which relation leads to populates the type of the
|
||||||
@ -69,6 +69,25 @@ How to treat child rows on delete of parent (the one where FK is defined) model.
|
|||||||
|
|
||||||
`(Tuple[Any, List, Any])`: tuple with target pydantic type, list of fk constraints and target col type
|
`(Tuple[Any, List, Any])`: tuple with target pydantic type, list of fk constraints and target col type
|
||||||
|
|
||||||
|
<a name="fields.foreign_key.validate_not_allowed_fields"></a>
|
||||||
|
#### validate\_not\_allowed\_fields
|
||||||
|
|
||||||
|
```python
|
||||||
|
validate_not_allowed_fields(kwargs: Dict) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Verifies if not allowed parameters are set on relation models.
|
||||||
|
Usually they are omitted later anyway but this way it's explicitly
|
||||||
|
notify the user that it's not allowed/ supported.
|
||||||
|
|
||||||
|
**Raises**:
|
||||||
|
|
||||||
|
- `ModelDefinitionError`: if any forbidden field is set
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `kwargs (Dict)`: dict of kwargs to verify passed to relation field
|
||||||
|
|
||||||
<a name="fields.foreign_key.UniqueColumns"></a>
|
<a name="fields.foreign_key.UniqueColumns"></a>
|
||||||
## UniqueColumns Objects
|
## UniqueColumns Objects
|
||||||
|
|
||||||
@ -94,7 +113,7 @@ to produce sqlalchemy.ForeignKeys
|
|||||||
#### ForeignKey
|
#### ForeignKey
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ForeignKey(to: "ToType", *, name: str = None, unique: bool = False, nullable: bool = True, related_name: str = None, virtual: bool = False, onupdate: str = None, ondelete: str = None, **kwargs: Any, ,) -> Any
|
ForeignKey(to: "ToType", *, name: str = None, unique: bool = False, nullable: bool = True, related_name: str = None, virtual: bool = False, onupdate: str = None, ondelete: str = None, **kwargs: Any, ,) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Despite a name it's a function that returns constructed ForeignKeyField.
|
Despite a name it's a function that returns constructed ForeignKeyField.
|
||||||
@ -134,8 +153,7 @@ Actual class returned from ForeignKey function call and stored in model_fields.
|
|||||||
#### get\_source\_related\_name
|
#### get\_source\_related\_name
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_source_related_name() -> str
|
||||||
| get_source_related_name(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name to use for source relation name.
|
Returns name to use for source relation name.
|
||||||
@ -150,8 +168,7 @@ It's either set as `related_name` or by default it's owner model. get_name + 's'
|
|||||||
#### get\_related\_name
|
#### get\_related\_name
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_related_name() -> str
|
||||||
| get_related_name(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name to use for reverse relation.
|
Returns name to use for reverse relation.
|
||||||
@ -161,12 +178,37 @@ It's either set as `related_name` or by default it's owner model. get_name + 's'
|
|||||||
|
|
||||||
`(str)`: name of the related_name or default related name.
|
`(str)`: name of the related_name or default related name.
|
||||||
|
|
||||||
|
<a name="fields.foreign_key.ForeignKeyField.default_target_field_name"></a>
|
||||||
|
#### default\_target\_field\_name
|
||||||
|
|
||||||
|
```python
|
||||||
|
| default_target_field_name() -> str
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns default target model name on through model.
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(str)`: name of the field
|
||||||
|
|
||||||
|
<a name="fields.foreign_key.ForeignKeyField.default_source_field_name"></a>
|
||||||
|
#### default\_source\_field\_name
|
||||||
|
|
||||||
|
```python
|
||||||
|
| default_source_field_name() -> str
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns default target model name on through model.
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(str)`: name of the field
|
||||||
|
|
||||||
<a name="fields.foreign_key.ForeignKeyField.evaluate_forward_ref"></a>
|
<a name="fields.foreign_key.ForeignKeyField.evaluate_forward_ref"></a>
|
||||||
#### evaluate\_forward\_ref
|
#### evaluate\_forward\_ref
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| evaluate_forward_ref(globalns: Any, localns: Any) -> None
|
||||||
| evaluate_forward_ref(cls, globalns: Any, localns: Any) -> None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Evaluates the ForwardRef to actual Field based on global and local namespaces
|
Evaluates the ForwardRef to actual Field based on global and local namespaces
|
||||||
@ -184,8 +226,7 @@ Evaluates the ForwardRef to actual Field based on global and local namespaces
|
|||||||
#### \_extract\_model\_from\_sequence
|
#### \_extract\_model\_from\_sequence
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| _extract_model_from_sequence(value: List, child: "Model", to_register: bool) -> List["Model"]
|
||||||
| _extract_model_from_sequence(cls, value: List, child: "Model", to_register: bool) -> List["Model"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Takes a list of Models and registers them on parent.
|
Takes a list of Models and registers them on parent.
|
||||||
@ -207,8 +248,7 @@ Used in reverse FK relations.
|
|||||||
#### \_register\_existing\_model
|
#### \_register\_existing\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| _register_existing_model(value: "Model", child: "Model", to_register: bool) -> "Model"
|
||||||
| _register_existing_model(cls, value: "Model", child: "Model", to_register: bool) -> "Model"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Takes already created instance and registers it for parent.
|
Takes already created instance and registers it for parent.
|
||||||
@ -230,8 +270,7 @@ Used in reverse FK relations and normal FK for single models.
|
|||||||
#### \_construct\_model\_from\_dict
|
#### \_construct\_model\_from\_dict
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| _construct_model_from_dict(value: dict, child: "Model", to_register: bool) -> "Model"
|
||||||
| _construct_model_from_dict(cls, value: dict, child: "Model", to_register: bool) -> "Model"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Takes a dictionary, creates a instance and registers it for parent.
|
Takes a dictionary, creates a instance and registers it for parent.
|
||||||
@ -254,8 +293,7 @@ Used in normal FK for dictionaries.
|
|||||||
#### \_construct\_model\_from\_pk
|
#### \_construct\_model\_from\_pk
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| _construct_model_from_pk(value: Any, child: "Model", to_register: bool) -> "Model"
|
||||||
| _construct_model_from_pk(cls, value: Any, child: "Model", to_register: bool) -> "Model"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Takes a pk value, creates a dummy instance and registers it for parent.
|
Takes a pk value, creates a dummy instance and registers it for parent.
|
||||||
@ -277,8 +315,7 @@ Used in normal FK for dictionaries.
|
|||||||
#### register\_relation
|
#### register\_relation
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| register_relation(model: "Model", child: "Model") -> None
|
||||||
| register_relation(cls, model: "Model", child: "Model") -> None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers relation between parent and child in relation manager.
|
Registers relation between parent and child in relation manager.
|
||||||
@ -296,8 +333,7 @@ Used in Metaclass and sometimes some relations are missing
|
|||||||
#### has\_unresolved\_forward\_refs
|
#### has\_unresolved\_forward\_refs
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| has_unresolved_forward_refs() -> bool
|
||||||
| has_unresolved_forward_refs(cls) -> bool
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Verifies if the filed has any ForwardRefs that require updating before the
|
Verifies if the filed has any ForwardRefs that require updating before the
|
||||||
@ -311,8 +347,7 @@ model can be used.
|
|||||||
#### expand\_relationship
|
#### expand\_relationship
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| expand_relationship(value: Any, child: Union["Model", "NewBaseModel"], to_register: bool = True) -> Optional[Union["Model", List["Model"]]]
|
||||||
| expand_relationship(cls, value: Any, child: Union["Model", "NewBaseModel"], to_register: bool = True) -> Optional[Union["Model", List["Model"]]]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For relations the child model is first constructed (if needed),
|
For relations the child model is first constructed (if needed),
|
||||||
@ -336,8 +371,7 @@ Selects the appropriate constructor based on a passed value.
|
|||||||
#### get\_relation\_name
|
#### get\_relation\_name
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_relation_name() -> str
|
||||||
| get_relation_name(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name of the relation, which can be a own name or through model
|
Returns name of the relation, which can be a own name or through model
|
||||||
@ -351,8 +385,7 @@ names for m2m models
|
|||||||
#### get\_source\_model
|
#### get\_source\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_source_model() -> Type["Model"]
|
||||||
| get_source_model(cls) -> Type["Model"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns model from which the relation comes -> either owner or through model
|
Returns model from which the relation comes -> either owner or through model
|
||||||
|
|||||||
@ -1,6 +1,19 @@
|
|||||||
<a name="fields.many_to_many"></a>
|
<a name="fields.many_to_many"></a>
|
||||||
# fields.many\_to\_many
|
# fields.many\_to\_many
|
||||||
|
|
||||||
|
<a name="fields.many_to_many.forbid_through_relations"></a>
|
||||||
|
#### forbid\_through\_relations
|
||||||
|
|
||||||
|
```python
|
||||||
|
forbid_through_relations(through: Type["Model"]) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Verifies if the through model does not have relations.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `through (Type['Model])`: through Model to be checked
|
||||||
|
|
||||||
<a name="fields.many_to_many.populate_m2m_params_based_on_to_model"></a>
|
<a name="fields.many_to_many.populate_m2m_params_based_on_to_model"></a>
|
||||||
#### populate\_m2m\_params\_based\_on\_to\_model
|
#### populate\_m2m\_params\_based\_on\_to\_model
|
||||||
|
|
||||||
@ -24,7 +37,7 @@ pydantic field to use and type of the target column field.
|
|||||||
#### ManyToMany
|
#### ManyToMany
|
||||||
|
|
||||||
```python
|
```python
|
||||||
ManyToMany(to: "ToType", through: Optional["ToType"] = None, *, name: str = None, unique: bool = False, virtual: bool = False, **kwargs: Any, ,) -> Any
|
ManyToMany(to: "ToType", through: Optional["ToType"] = None, *, name: str = None, unique: bool = False, virtual: bool = False, **kwargs: Any, ,) -> "RelationProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Despite a name it's a function that returns constructed ManyToManyField.
|
Despite a name it's a function that returns constructed ManyToManyField.
|
||||||
@ -60,8 +73,7 @@ Actual class returned from ManyToMany function call and stored in model_fields.
|
|||||||
#### get\_source\_related\_name
|
#### get\_source\_related\_name
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_source_related_name() -> str
|
||||||
| get_source_related_name(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name to use for source relation name.
|
Returns name to use for source relation name.
|
||||||
@ -72,40 +84,11 @@ It's either set as `related_name` or by default it's field name.
|
|||||||
|
|
||||||
`(str)`: name of the related_name or default related name.
|
`(str)`: name of the related_name or default related name.
|
||||||
|
|
||||||
<a name="fields.many_to_many.ManyToManyField.default_target_field_name"></a>
|
|
||||||
#### default\_target\_field\_name
|
|
||||||
|
|
||||||
```python
|
|
||||||
| @classmethod
|
|
||||||
| default_target_field_name(cls) -> str
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns default target model name on through model.
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(str)`: name of the field
|
|
||||||
|
|
||||||
<a name="fields.many_to_many.ManyToManyField.default_source_field_name"></a>
|
|
||||||
#### default\_source\_field\_name
|
|
||||||
|
|
||||||
```python
|
|
||||||
| @classmethod
|
|
||||||
| default_source_field_name(cls) -> str
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns default target model name on through model.
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(str)`: name of the field
|
|
||||||
|
|
||||||
<a name="fields.many_to_many.ManyToManyField.has_unresolved_forward_refs"></a>
|
<a name="fields.many_to_many.ManyToManyField.has_unresolved_forward_refs"></a>
|
||||||
#### has\_unresolved\_forward\_refs
|
#### has\_unresolved\_forward\_refs
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| has_unresolved_forward_refs() -> bool
|
||||||
| has_unresolved_forward_refs(cls) -> bool
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Verifies if the filed has any ForwardRefs that require updating before the
|
Verifies if the filed has any ForwardRefs that require updating before the
|
||||||
@ -119,8 +102,7 @@ model can be used.
|
|||||||
#### evaluate\_forward\_ref
|
#### evaluate\_forward\_ref
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| evaluate_forward_ref(globalns: Any, localns: Any) -> None
|
||||||
| evaluate_forward_ref(cls, globalns: Any, localns: Any) -> None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Evaluates the ForwardRef to actual Field based on global and local namespaces
|
Evaluates the ForwardRef to actual Field based on global and local namespaces
|
||||||
@ -138,8 +120,7 @@ Evaluates the ForwardRef to actual Field based on global and local namespaces
|
|||||||
#### get\_relation\_name
|
#### get\_relation\_name
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_relation_name() -> str
|
||||||
| get_relation_name(cls) -> str
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name of the relation, which can be a own name or through model
|
Returns name of the relation, which can be a own name or through model
|
||||||
@ -153,8 +134,7 @@ names for m2m models
|
|||||||
#### get\_source\_model
|
#### get\_source\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| get_source_model() -> Type["Model"]
|
||||||
| get_source_model(cls) -> Type["Model"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns model from which the relation comes -> either owner or through model
|
Returns model from which the relation comes -> either owner or through model
|
||||||
@ -167,8 +147,7 @@ Returns model from which the relation comes -> either owner or through model
|
|||||||
#### create\_default\_through\_model
|
#### create\_default\_through\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| create_default_through_model() -> None
|
||||||
| create_default_through_model(cls) -> None
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Creates default empty through model if no additional fields are required.
|
Creates default empty through model if no additional fields are required.
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### is\_field\_an\_forward\_ref
|
#### is\_field\_an\_forward\_ref
|
||||||
|
|
||||||
```python
|
```python
|
||||||
is_field_an_forward_ref(field: Type["BaseField"]) -> bool
|
is_field_an_forward_ref(field: "BaseField") -> bool
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if field is a relation field and whether any of the referenced models
|
Checks if field is a relation field and whether any of the referenced models
|
||||||
@ -91,7 +91,7 @@ extraction of ormar model_fields.
|
|||||||
#### group\_related\_list
|
#### group\_related\_list
|
||||||
|
|
||||||
```python
|
```python
|
||||||
group_related_list(list_: List) -> Dict
|
group_related_list(list_: List) -> collections.OrderedDict
|
||||||
```
|
```
|
||||||
|
|
||||||
Translates the list of related strings into a dictionary.
|
Translates the list of related strings into a dictionary.
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### create\_pydantic\_field
|
#### create\_pydantic\_field
|
||||||
|
|
||||||
```python
|
```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: "ManyToManyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers pydantic field on through model that leads to passed model
|
Registers pydantic field on through model that leads to passed model
|
||||||
@ -38,32 +38,6 @@ field_name. Returns a pydantic field with type of field_name field type.
|
|||||||
|
|
||||||
`(pydantic.ModelField)`: newly created pydantic field
|
`(pydantic.ModelField)`: newly created pydantic field
|
||||||
|
|
||||||
<a name="models.helpers.pydantic.populate_default_pydantic_field_value"></a>
|
|
||||||
#### populate\_default\_pydantic\_field\_value
|
|
||||||
|
|
||||||
```python
|
|
||||||
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
|
|
||||||
(so the default_value declared on ormar model if set)
|
|
||||||
and converts it to pydantic.FieldInfo
|
|
||||||
that pydantic is able to extract later.
|
|
||||||
|
|
||||||
On FieldInfo there are saved all needed params like max_length of the string
|
|
||||||
and other constraints that pydantic can use to build
|
|
||||||
it's own field validation used by ormar.
|
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `ormar_field (ormar Field)`: field to convert
|
|
||||||
- `field_name (str)`: field to convert name
|
|
||||||
- `attrs (Dict)`: current class namespace
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(Dict)`: updated namespace dict
|
|
||||||
|
|
||||||
<a name="models.helpers.pydantic.populate_pydantic_default_values"></a>
|
<a name="models.helpers.pydantic.populate_pydantic_default_values"></a>
|
||||||
#### populate\_pydantic\_default\_values
|
#### populate\_pydantic\_default\_values
|
||||||
|
|
||||||
@ -76,7 +50,7 @@ dictionary of the class. Fields declared on model are all subclasses of the
|
|||||||
BaseField class.
|
BaseField class.
|
||||||
|
|
||||||
Trigger conversion of ormar field into pydantic FieldInfo, which has all needed
|
Trigger conversion of ormar field into pydantic FieldInfo, which has all needed
|
||||||
paramaters saved.
|
parameters saved.
|
||||||
|
|
||||||
Overwrites the annotations of ormar fields to corresponding types declared on
|
Overwrites the annotations of ormar fields to corresponding types declared on
|
||||||
ormar fields (constructed dynamically for relations).
|
ormar fields (constructed dynamically for relations).
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### register\_relation\_on\_build
|
#### register\_relation\_on\_build
|
||||||
|
|
||||||
```python
|
```python
|
||||||
register_relation_on_build(field: Type["ForeignKeyField"]) -> None
|
register_relation_on_build(field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers ForeignKey relation in alias_manager to set a table_prefix.
|
Registers ForeignKey relation in alias_manager to set a table_prefix.
|
||||||
@ -23,7 +23,7 @@ aliases for proper sql joins.
|
|||||||
#### register\_many\_to\_many\_relation\_on\_build
|
#### register\_many\_to\_many\_relation\_on\_build
|
||||||
|
|
||||||
```python
|
```python
|
||||||
register_many_to_many_relation_on_build(field: Type["ManyToManyField"]) -> None
|
register_many_to_many_relation_on_build(field: "ManyToManyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers connection between through model and both sides of the m2m relation.
|
Registers connection between through model and both sides of the m2m relation.
|
||||||
@ -43,7 +43,7 @@ By default relation name is a model.name.lower().
|
|||||||
#### expand\_reverse\_relationship
|
#### expand\_reverse\_relationship
|
||||||
|
|
||||||
```python
|
```python
|
||||||
expand_reverse_relationship(model_field: Type["ForeignKeyField"]) -> None
|
expand_reverse_relationship(model_field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
If the reverse relation has not been set before it's set here.
|
If the reverse relation has not been set before it's set here.
|
||||||
@ -76,7 +76,7 @@ If the reverse relation has not been set before it's set here.
|
|||||||
#### register\_reverse\_model\_fields
|
#### register\_reverse\_model\_fields
|
||||||
|
|
||||||
```python
|
```python
|
||||||
register_reverse_model_fields(model_field: Type["ForeignKeyField"]) -> None
|
register_reverse_model_fields(model_field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers reverse ForeignKey field on related model.
|
Registers reverse ForeignKey field on related model.
|
||||||
@ -93,7 +93,7 @@ Autogenerated reverse fields also set related_name to the original field name.
|
|||||||
#### register\_through\_shortcut\_fields
|
#### register\_through\_shortcut\_fields
|
||||||
|
|
||||||
```python
|
```python
|
||||||
register_through_shortcut_fields(model_field: Type["ManyToManyField"]) -> None
|
register_through_shortcut_fields(model_field: "ManyToManyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers m2m relation through shortcut on both ends of the relation.
|
Registers m2m relation through shortcut on both ends of the relation.
|
||||||
@ -106,7 +106,7 @@ Registers m2m relation through shortcut on both ends of the relation.
|
|||||||
#### register\_relation\_in\_alias\_manager
|
#### register\_relation\_in\_alias\_manager
|
||||||
|
|
||||||
```python
|
```python
|
||||||
register_relation_in_alias_manager(field: Type["ForeignKeyField"]) -> None
|
register_relation_in_alias_manager(field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers the relation (and reverse relation) in alias manager.
|
Registers the relation (and reverse relation) in alias manager.
|
||||||
@ -125,7 +125,7 @@ fk - register_relation_on_build
|
|||||||
#### verify\_related\_name\_dont\_duplicate
|
#### verify\_related\_name\_dont\_duplicate
|
||||||
|
|
||||||
```python
|
```python
|
||||||
verify_related_name_dont_duplicate(related_name: str, model_field: Type["ForeignKeyField"]) -> None
|
verify_related_name_dont_duplicate(related_name: str, model_field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Verifies whether the used related_name (regardless of the fact if user defined or
|
Verifies whether the used related_name (regardless of the fact if user defined or
|
||||||
@ -150,7 +150,7 @@ model
|
|||||||
#### reverse\_field\_not\_already\_registered
|
#### reverse\_field\_not\_already\_registered
|
||||||
|
|
||||||
```python
|
```python
|
||||||
reverse_field_not_already_registered(model_field: Type["ForeignKeyField"]) -> bool
|
reverse_field_not_already_registered(model_field: "ForeignKeyField") -> bool
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if child is already registered in parents pydantic fields.
|
Checks if child is already registered in parents pydantic fields.
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### adjust\_through\_many\_to\_many\_model
|
#### adjust\_through\_many\_to\_many\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
adjust_through_many_to_many_model(model_field: Type["ManyToManyField"]) -> None
|
adjust_through_many_to_many_model(model_field: "ManyToManyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers m2m relation on through model.
|
Registers m2m relation on through model.
|
||||||
@ -21,7 +21,7 @@ Sets pydantic fields with child and parent model types.
|
|||||||
#### create\_and\_append\_m2m\_fk
|
#### create\_and\_append\_m2m\_fk
|
||||||
|
|
||||||
```python
|
```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: "ManyToManyField", field_name: str) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers sqlalchemy Column with sqlalchemy.ForeignKey leading to the model.
|
Registers sqlalchemy Column with sqlalchemy.ForeignKey leading to the model.
|
||||||
@ -98,6 +98,72 @@ or pkname validation fails.
|
|||||||
|
|
||||||
`(Tuple[Optional[str], List[sqlalchemy.Column]])`: pkname, list of sqlalchemy columns
|
`(Tuple[Optional[str], List[sqlalchemy.Column]])`: pkname, list of sqlalchemy columns
|
||||||
|
|
||||||
|
<a name="models.helpers.sqlalchemy._process_fields"></a>
|
||||||
|
#### \_process\_fields
|
||||||
|
|
||||||
|
```python
|
||||||
|
_process_fields(model_fields: Dict, new_model: Type["Model"]) -> Tuple[Optional[str], List[sqlalchemy.Column]]
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper method.
|
||||||
|
|
||||||
|
Populates pkname and columns.
|
||||||
|
Trigger validation of primary_key - only one and required pk can be set,
|
||||||
|
cannot be pydantic_only.
|
||||||
|
|
||||||
|
Append fields to columns if it's not pydantic_only,
|
||||||
|
virtual ForeignKey or ManyToMany field.
|
||||||
|
|
||||||
|
Sets `owner` on each model_field as reference to newly created Model.
|
||||||
|
|
||||||
|
**Raises**:
|
||||||
|
|
||||||
|
- `ModelDefinitionError`: if validation of related_names fail,
|
||||||
|
or pkname validation fails.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `model_fields (Dict[str, ormar.Field])`: dictionary of declared ormar model fields
|
||||||
|
- `new_model (Model class)`:
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Tuple[Optional[str], List[sqlalchemy.Column]])`: pkname, list of sqlalchemy columns
|
||||||
|
|
||||||
|
<a name="models.helpers.sqlalchemy._is_through_model_not_set"></a>
|
||||||
|
#### \_is\_through\_model\_not\_set
|
||||||
|
|
||||||
|
```python
|
||||||
|
_is_through_model_not_set(field: "BaseField") -> bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Alias to if check that verifies if through model was created.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `field ("BaseField")`: field to check
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(bool)`: result of the check
|
||||||
|
|
||||||
|
<a name="models.helpers.sqlalchemy._is_db_field"></a>
|
||||||
|
#### \_is\_db\_field
|
||||||
|
|
||||||
|
```python
|
||||||
|
_is_db_field(field: "BaseField") -> bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Alias to if check that verifies if field should be included in database.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `field ("BaseField")`: field to check
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(bool)`: result of the check
|
||||||
|
|
||||||
<a name="models.helpers.sqlalchemy.populate_meta_tablename_columns_and_pk"></a>
|
<a name="models.helpers.sqlalchemy.populate_meta_tablename_columns_and_pk"></a>
|
||||||
#### populate\_meta\_tablename\_columns\_and\_pk
|
#### populate\_meta\_tablename\_columns\_and\_pk
|
||||||
|
|
||||||
@ -165,7 +231,7 @@ It populates name, metadata, columns and constraints.
|
|||||||
#### update\_column\_definition
|
#### update\_column\_definition
|
||||||
|
|
||||||
```python
|
```python
|
||||||
update_column_definition(model: Union[Type["Model"], Type["NewBaseModel"]], field: Type["ForeignKeyField"]) -> None
|
update_column_definition(model: Union[Type["Model"], Type["NewBaseModel"]], field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates a column with a new type column based on updated parameters in FK fields.
|
Updates a column with a new type column based on updated parameters in FK fields.
|
||||||
@ -173,7 +239,7 @@ Updates a column with a new type column based on updated parameters in FK fields
|
|||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `model (Type["Model"])`: model on which columns needs to be updated
|
- `model (Type["Model"])`: model on which columns needs to be updated
|
||||||
- `field (Type[ForeignKeyField])`: field with column definition that requires update
|
- `field (ForeignKeyField)`: field with column definition that requires update
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### check\_if\_field\_has\_choices
|
#### check\_if\_field\_has\_choices
|
||||||
|
|
||||||
```python
|
```python
|
||||||
check_if_field_has_choices(field: Type[BaseField]) -> bool
|
check_if_field_has_choices(field: BaseField) -> bool
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if given field has choices populated.
|
Checks if given field has choices populated.
|
||||||
@ -23,7 +23,7 @@ A if it has one, a validator for this field needs to be attached.
|
|||||||
#### convert\_choices\_if\_needed
|
#### convert\_choices\_if\_needed
|
||||||
|
|
||||||
```python
|
```python
|
||||||
convert_choices_if_needed(field: Type["BaseField"], value: Any) -> Tuple[Any, List]
|
convert_choices_if_needed(field: "BaseField", value: Any) -> Tuple[Any, List]
|
||||||
```
|
```
|
||||||
|
|
||||||
Converts dates to isoformat as fastapi can check this condition in routes
|
Converts dates to isoformat as fastapi can check this condition in routes
|
||||||
@ -37,7 +37,7 @@ Converts decimal to float with given scale.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `field (Type[BaseField])`: ormar field to check with choices
|
- `field (BaseField)`: ormar field to check with choices
|
||||||
- `values (Dict)`: current values of the model to verify
|
- `values (Dict)`: current values of the model to verify
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
@ -48,7 +48,7 @@ Converts decimal to float with given scale.
|
|||||||
#### validate\_choices
|
#### validate\_choices
|
||||||
|
|
||||||
```python
|
```python
|
||||||
validate_choices(field: Type["BaseField"], value: Any) -> None
|
validate_choices(field: "BaseField", value: Any) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Validates if given value is in provided choices.
|
Validates if given value is in provided choices.
|
||||||
@ -59,7 +59,7 @@ Validates if given value is in provided choices.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `field (Type[BaseField])`: field to validate
|
- `field (BaseField)`: field to validate
|
||||||
- `value (Any)`: value of the field
|
- `value (Any)`: value of the field
|
||||||
|
|
||||||
<a name="models.helpers.validation.choices_validator"></a>
|
<a name="models.helpers.validation.choices_validator"></a>
|
||||||
|
|||||||
@ -78,12 +78,12 @@ Primary key field is always added and cannot be excluded (will be added anyway).
|
|||||||
|
|
||||||
`(List[str])`: list of column field names or aliases
|
`(List[str])`: list of column field names or aliases
|
||||||
|
|
||||||
<a name="models.mixins.excludable_mixin.ExcludableMixin._update_excluded_with_related_not_required"></a>
|
<a name="models.mixins.excludable_mixin.ExcludableMixin._update_excluded_with_related"></a>
|
||||||
#### \_update\_excluded\_with\_related\_not\_required
|
#### \_update\_excluded\_with\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| _update_excluded_with_related_not_required(cls, exclude: Union["AbstractSetIntStr", "MappingIntStrAny", None], nested: bool = False) -> Union[Set, Dict]
|
| _update_excluded_with_related(cls, exclude: Union[Set, Dict, None]) -> Set
|
||||||
```
|
```
|
||||||
|
|
||||||
Used during generation of the dict().
|
Used during generation of the dict().
|
||||||
@ -96,7 +96,6 @@ exclusion, for nested models all related models are excluded.
|
|||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `exclude (Union[Set, Dict, None])`: set/dict with fields to exclude
|
- `exclude (Union[Set, Dict, None])`: set/dict with fields to exclude
|
||||||
- `nested (bool)`: flag setting nested models (child of previous one, not main one)
|
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ in the end all parent (main) models should be unique.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| merge_instances_list(cls, result_rows: Sequence["Model"]) -> Sequence["Model"]
|
| merge_instances_list(cls, result_rows: List["Model"]) -> List["Model"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Merges a list of models into list of unique models.
|
Merges a list of models into list of unique models.
|
||||||
@ -41,7 +41,7 @@ populated, each instance is one row in db and some models can duplicate
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| merge_two_instances(cls, one: "Model", other: "Model") -> "Model"
|
| merge_two_instances(cls, one: "Model", other: "Model", relation_map: Dict = None) -> "Model"
|
||||||
```
|
```
|
||||||
|
|
||||||
Merges current (other) Model and previous one (one) and returns the current
|
Merges current (other) Model and previous one (one) and returns the current
|
||||||
@ -51,6 +51,7 @@ If needed it's calling itself recurrently and merges also children models.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
|
- `relation_map (Dict)`: map of models relations to follow
|
||||||
- `one (Model)`: previous model instance
|
- `one (Model)`: previous model instance
|
||||||
- `other (Model)`: current model instance
|
- `other (Model)`: current model instance
|
||||||
|
|
||||||
@ -58,3 +59,30 @@ If needed it's calling itself recurrently and merges also children models.
|
|||||||
|
|
||||||
`(Model)`: current Model instance with data merged from previous one.
|
`(Model)`: current Model instance with data merged from previous one.
|
||||||
|
|
||||||
|
<a name="models.mixins.merge_mixin.MergeModelMixin._merge_items_lists"></a>
|
||||||
|
#### \_merge\_items\_lists
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @classmethod
|
||||||
|
| _merge_items_lists(cls, field_name: str, current_field: List, other_value: List, relation_map: Optional[Dict]) -> List
|
||||||
|
```
|
||||||
|
|
||||||
|
Takes two list of nested models and process them going deeper
|
||||||
|
according with the map.
|
||||||
|
|
||||||
|
If model from one's list is in other -> they are merged with relations
|
||||||
|
to follow passed from map.
|
||||||
|
|
||||||
|
If one's model is not in other it's simply appended to the list.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `field_name (str)`: name of the current relation field
|
||||||
|
- `current_field (List[Model])`: list of nested models from one model
|
||||||
|
- `other_value (List[Model])`: list of nested models from other model
|
||||||
|
- `relation_map (Dict)`: map of relations to follow
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(List[Model])`: merged list of models
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ or field name specified by related parameter.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| get_related_field_name(cls, target_field: Type["ForeignKeyField"]) -> str
|
| get_related_field_name(cls, target_field: "ForeignKeyField") -> str
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns name of the relation field that should be used in prefetch query.
|
Returns name of the relation field that should be used in prefetch query.
|
||||||
|
|||||||
@ -30,7 +30,7 @@ related fields.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| extract_related_fields(cls) -> List
|
| extract_related_fields(cls) -> List["ForeignKeyField"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns List of ormar Fields for all relations declared on a model.
|
Returns List of ormar Fields for all relations declared on a model.
|
||||||
@ -45,7 +45,7 @@ List is cached in cls._related_fields for quicker access.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| extract_through_names(cls) -> Set
|
| extract_through_names(cls) -> Set[str]
|
||||||
```
|
```
|
||||||
|
|
||||||
Extracts related fields through names which are shortcuts to through models.
|
Extracts related fields through names which are shortcuts to through models.
|
||||||
@ -84,43 +84,35 @@ related fields that are not stored as foreign keys on given model.
|
|||||||
|
|
||||||
`(Set)`: set of model fields with non fk relation fields excluded
|
`(Set)`: set of model fields with non fk relation fields excluded
|
||||||
|
|
||||||
<a name="models.mixins.relation_mixin.RelationMixin._exclude_related_names_not_required"></a>
|
|
||||||
#### \_exclude\_related\_names\_not\_required
|
|
||||||
|
|
||||||
```python
|
|
||||||
| @classmethod
|
|
||||||
| _exclude_related_names_not_required(cls, nested: bool = False) -> Set
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns a set of non mandatory related models field names.
|
|
||||||
|
|
||||||
For a main model (not nested) only nullable related field names are returned,
|
|
||||||
for nested models all related models are returned.
|
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `nested (bool)`: flag setting nested models (child of previous one, not main one)
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(Set)`: set of non mandatory related fields
|
|
||||||
|
|
||||||
<a name="models.mixins.relation_mixin.RelationMixin._iterate_related_models"></a>
|
<a name="models.mixins.relation_mixin.RelationMixin._iterate_related_models"></a>
|
||||||
#### \_iterate\_related\_models
|
#### \_iterate\_related\_models
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| _iterate_related_models(cls, visited: Set[Union[Type["Model"], Type["RelationMixin"]]] = None, source_relation: str = None, source_model: Union[Type["Model"], Type["RelationMixin"]] = None) -> List[str]
|
| _iterate_related_models(cls, node_list: NodeList = None, source_relation: str = None) -> List[str]
|
||||||
```
|
```
|
||||||
|
|
||||||
Iterates related models recursively to extract relation strings of
|
Iterates related models recursively to extract relation strings of
|
||||||
nested not visited models.
|
nested not visited models.
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(List[str])`: list of relation strings to be passed to select_related
|
||||||
|
|
||||||
|
<a name="models.mixins.relation_mixin.RelationMixin._get_final_relations"></a>
|
||||||
|
#### \_get\_final\_relations
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @staticmethod
|
||||||
|
| _get_final_relations(processed_relations: List, source_relation: Optional[str]) -> List[str]
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper method to prefix nested relation strings with current source relation
|
||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `visited (Set[str])`: set of already visited models
|
- `processed_relations (List[str])`: list of already processed relation str
|
||||||
- `source_relation (str)`: name of the current relation
|
- `source_relation (str)`: name of the current relation
|
||||||
- `source_model (Type["Model"])`: model from which relation comes in nested relations
|
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,25 @@ Translate columns into aliases (db names).
|
|||||||
|
|
||||||
`(Dict[str, str])`: dictionary of model that is about to be saved
|
`(Dict[str, str])`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
|
<a name="models.mixins.save_mixin.SavePrepareMixin._remove_not_ormar_fields"></a>
|
||||||
|
#### \_remove\_not\_ormar\_fields
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @classmethod
|
||||||
|
| _remove_not_ormar_fields(cls, new_kwargs: dict) -> dict
|
||||||
|
```
|
||||||
|
|
||||||
|
Removes primary key for if it's nullable or autoincrement pk field,
|
||||||
|
and it's set to None.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `new_kwargs (Dict[str, str])`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Dict[str, str])`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
<a name="models.mixins.save_mixin.SavePrepareMixin._remove_pk_from_kwargs"></a>
|
<a name="models.mixins.save_mixin.SavePrepareMixin._remove_pk_from_kwargs"></a>
|
||||||
#### \_remove\_pk\_from\_kwargs
|
#### \_remove\_pk\_from\_kwargs
|
||||||
|
|
||||||
@ -52,6 +71,25 @@ and it's set to None.
|
|||||||
|
|
||||||
`(Dict[str, str])`: dictionary of model that is about to be saved
|
`(Dict[str, str])`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
|
<a name="models.mixins.save_mixin.SavePrepareMixin.parse_non_db_fields"></a>
|
||||||
|
#### parse\_non\_db\_fields
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @classmethod
|
||||||
|
| parse_non_db_fields(cls, model_dict: Dict) -> Dict
|
||||||
|
```
|
||||||
|
|
||||||
|
Receives dictionary of model that is about to be saved and changes uuid fields
|
||||||
|
to strings in bulk_update.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `model_dict (Dict)`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Dict)`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
<a name="models.mixins.save_mixin.SavePrepareMixin.substitute_models_with_pks"></a>
|
<a name="models.mixins.save_mixin.SavePrepareMixin.substitute_models_with_pks"></a>
|
||||||
#### substitute\_models\_with\_pks
|
#### substitute\_models\_with\_pks
|
||||||
|
|
||||||
@ -110,3 +148,73 @@ fields with choices set to see if the value is allowed.
|
|||||||
|
|
||||||
`(Dict)`: dictionary of model that is about to be saved
|
`(Dict)`: dictionary of model that is about to be saved
|
||||||
|
|
||||||
|
<a name="models.mixins.save_mixin.SavePrepareMixin._upsert_model"></a>
|
||||||
|
#### \_upsert\_model
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @staticmethod
|
||||||
|
| async _upsert_model(instance: "Model", save_all: bool, previous_model: Optional["Model"], relation_field: Optional["ForeignKeyField"], update_count: int) -> int
|
||||||
|
```
|
||||||
|
|
||||||
|
Method updates given instance if:
|
||||||
|
|
||||||
|
* instance is not saved or
|
||||||
|
* instance have no pk or
|
||||||
|
* save_all=True flag is set
|
||||||
|
|
||||||
|
and instance is not __pk_only__.
|
||||||
|
|
||||||
|
If relation leading to instance is a ManyToMany also the through model is saved
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `instance (Model)`: current model to upsert
|
||||||
|
- `save_all (bool)`: flag if all models should be saved or only not saved ones
|
||||||
|
- `relation_field (Optional[ForeignKeyField])`: field with relation
|
||||||
|
- `previous_model (Model)`: previous model from which method came
|
||||||
|
- `update_count (int)`: no of updated models
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(int)`: no of updated models
|
||||||
|
|
||||||
|
<a name="models.mixins.save_mixin.SavePrepareMixin._upsert_through_model"></a>
|
||||||
|
#### \_upsert\_through\_model
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @staticmethod
|
||||||
|
| async _upsert_through_model(instance: "Model", previous_model: "Model", relation_field: "ForeignKeyField") -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Upsert through model for m2m relation.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `instance (Model)`: current model to upsert
|
||||||
|
- `relation_field (Optional[ForeignKeyField])`: field with relation
|
||||||
|
- `previous_model (Model)`: previous model from which method came
|
||||||
|
|
||||||
|
<a name="models.mixins.save_mixin.SavePrepareMixin._update_relation_list"></a>
|
||||||
|
#### \_update\_relation\_list
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async _update_relation_list(fields_list: Collection["ForeignKeyField"], follow: bool, save_all: bool, relation_map: Dict, update_count: int) -> int
|
||||||
|
```
|
||||||
|
|
||||||
|
Internal method used in save_related to follow deeper from
|
||||||
|
related models and update numbers of updated related instances.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `fields_list (Collection["ForeignKeyField"])`: list of ormar fields to follow and save
|
||||||
|
- `relation_map (Dict)`: map of relations to follow
|
||||||
|
- `follow (bool)`: flag to trigger deep save -
|
||||||
|
by default only directly related models are saved
|
||||||
|
with follow=True also related models of related models are saved
|
||||||
|
- `update_count (int)`: internal parameter for recursive calls -
|
||||||
|
number of updated instances
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(int)`: tuple of update count and visited
|
||||||
|
|
||||||
|
|||||||
@ -102,7 +102,7 @@ Updates Meta parameters in child from parent if needed.
|
|||||||
#### copy\_and\_replace\_m2m\_through\_model
|
#### copy\_and\_replace\_m2m\_through\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
copy_and_replace_m2m_through_model(field: Type[ManyToManyField], field_name: str, table_name: str, parent_fields: Dict, attrs: Dict, meta: ModelMeta, base_class: Type["Model"]) -> None
|
copy_and_replace_m2m_through_model(field: ManyToManyField, field_name: str, table_name: str, parent_fields: Dict, attrs: Dict, meta: ModelMeta, base_class: Type["Model"]) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Clones class with Through model for m2m relations, appends child name to the name
|
Clones class with Through model for m2m relations, appends child name to the name
|
||||||
@ -119,7 +119,7 @@ Removes the original sqlalchemy table from metadata if it was not removed.
|
|||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `base_class (Type["Model"])`: base class model
|
- `base_class (Type["Model"])`: base class model
|
||||||
- `field (Type[ManyToManyField])`: field with relations definition
|
- `field (ManyToManyField)`: field with relations definition
|
||||||
- `field_name (str)`: name of the relation field
|
- `field_name (str)`: name of the relation field
|
||||||
- `table_name (str)`: name of the table
|
- `table_name (str)`: name of the table
|
||||||
- `parent_fields (Dict)`: dictionary of fields to copy to new models from parent
|
- `parent_fields (Dict)`: dictionary of fields to copy to new models from parent
|
||||||
@ -130,9 +130,7 @@ Removes the original sqlalchemy table from metadata if it was not removed.
|
|||||||
#### copy\_data\_from\_parent\_model
|
#### copy\_data\_from\_parent\_model
|
||||||
|
|
||||||
```python
|
```python
|
||||||
copy_data_from_parent_model(base_class: Type["Model"], curr_class: type, attrs: Dict, model_fields: Dict[
|
copy_data_from_parent_model(base_class: Type["Model"], curr_class: type, attrs: Dict, model_fields: Dict[str, Union[BaseField, ForeignKeyField, ManyToManyField]]) -> Tuple[Dict, Dict]
|
||||||
str, Union[Type[BaseField], Type[ForeignKeyField], Type[ManyToManyField]]
|
|
||||||
]) -> Tuple[Dict, Dict]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy the key parameters [databse, metadata, property_fields and constraints]
|
Copy the key parameters [databse, metadata, property_fields and constraints]
|
||||||
@ -162,9 +160,7 @@ Since relation fields requires different related_name for different children
|
|||||||
#### extract\_from\_parents\_definition
|
#### extract\_from\_parents\_definition
|
||||||
|
|
||||||
```python
|
```python
|
||||||
extract_from_parents_definition(base_class: type, curr_class: type, attrs: Dict, model_fields: Dict[
|
extract_from_parents_definition(base_class: type, curr_class: type, attrs: Dict, model_fields: Dict[str, Union[BaseField, ForeignKeyField, ManyToManyField]]) -> Tuple[Dict, Dict]
|
||||||
str, Union[Type[BaseField], Type[ForeignKeyField], Type[ManyToManyField]]
|
|
||||||
]) -> Tuple[Dict, Dict]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Extracts fields from base classes if they have valid oramr fields.
|
Extracts fields from base classes if they have valid oramr fields.
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class ModelRow(NewBaseModel)
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| from_row(cls, row: sqlalchemy.engine.ResultProxy, source_model: Type["Model"], select_related: List = None, related_models: Any = None, related_field: Type["ForeignKeyField"] = None, excludable: ExcludableItems = None, current_relation_str: str = "", proxy_source_model: Optional[Type["Model"]] = None) -> Optional["Model"]
|
| from_row(cls, row: sqlalchemy.engine.ResultProxy, source_model: Type["Model"], select_related: List = None, related_models: Any = None, related_field: "ForeignKeyField" = None, excludable: ExcludableItems = None, current_relation_str: str = "", proxy_source_model: Optional[Type["Model"]] = None, used_prefixes: List[str] = None) -> Optional["Model"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Model method to convert raw sql row from database into ormar.Model instance.
|
Model method to convert raw sql row from database into ormar.Model instance.
|
||||||
@ -30,6 +30,7 @@ nested models in result.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
|
- `used_prefixes (List[str])`: list of already extracted prefixes
|
||||||
- `proxy_source_model (Optional[Type["ModelRow"]])`: source model from which querysetproxy is constructed
|
- `proxy_source_model (Optional[Type["ModelRow"]])`: source model from which querysetproxy is constructed
|
||||||
- `excludable (ExcludableItems)`: structure of fields to include and exclude
|
- `excludable (ExcludableItems)`: structure of fields to include and exclude
|
||||||
- `current_relation_str (str)`: name of the relation field
|
- `current_relation_str (str)`: name of the relation field
|
||||||
@ -37,18 +38,37 @@ nested models in result.
|
|||||||
- `row (sqlalchemy.engine.result.ResultProxy)`: raw result row from the database
|
- `row (sqlalchemy.engine.result.ResultProxy)`: raw result row from the database
|
||||||
- `select_related (List)`: list of names of related models fetched from database
|
- `select_related (List)`: list of names of related models fetched from database
|
||||||
- `related_models (Union[List, Dict])`: list or dict of related models
|
- `related_models (Union[List, Dict])`: list or dict of related models
|
||||||
- `related_field (Type[ForeignKeyField])`: field with relation declaration
|
- `related_field (ForeignKeyField)`: field with relation declaration
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
`(Optional[Model])`: returns model if model is populated from database
|
`(Optional[Model])`: returns model if model is populated from database
|
||||||
|
|
||||||
|
<a name="models.model_row.ModelRow._process_table_prefix"></a>
|
||||||
|
#### \_process\_table\_prefix
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @classmethod
|
||||||
|
| _process_table_prefix(cls, source_model: Type["Model"], current_relation_str: str, related_field: "ForeignKeyField", used_prefixes: List[str]) -> str
|
||||||
|
```
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `source_model (Type[Model])`: model on which relation was defined
|
||||||
|
- `current_relation_str (str)`: current relation string
|
||||||
|
- `related_field ("ForeignKeyField")`: field with relation declaration
|
||||||
|
- `used_prefixes (List[str])`: list of already extracted prefixes
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(str)`: table_prefix to use
|
||||||
|
|
||||||
<a name="models.model_row.ModelRow._populate_nested_models_from_row"></a>
|
<a name="models.model_row.ModelRow._populate_nested_models_from_row"></a>
|
||||||
#### \_populate\_nested\_models\_from\_row
|
#### \_populate\_nested\_models\_from\_row
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| _populate_nested_models_from_row(cls, item: dict, row: sqlalchemy.engine.ResultProxy, source_model: Type["Model"], related_models: Any, excludable: ExcludableItems, table_prefix: str, current_relation_str: str = None, proxy_source_model: Type["Model"] = None) -> dict
|
| _populate_nested_models_from_row(cls, item: dict, row: sqlalchemy.engine.ResultProxy, source_model: Type["Model"], related_models: Any, excludable: ExcludableItems, table_prefix: str, used_prefixes: List[str], current_relation_str: str = None, proxy_source_model: Type["Model"] = None) -> dict
|
||||||
```
|
```
|
||||||
|
|
||||||
Traverses structure of related models and populates the nested models
|
Traverses structure of related models and populates the nested models
|
||||||
@ -75,12 +95,48 @@ instances. In the end those instances are added to the final model dictionary.
|
|||||||
`(Dict)`: dictionary with keys corresponding to model fields names
|
`(Dict)`: dictionary with keys corresponding to model fields names
|
||||||
and values are database values
|
and values are database values
|
||||||
|
|
||||||
<a name="models.model_row.ModelRow.populate_through_instance"></a>
|
<a name="models.model_row.ModelRow._process_remainder_and_relation_string"></a>
|
||||||
#### populate\_through\_instance
|
#### \_process\_remainder\_and\_relation\_string
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @staticmethod
|
||||||
|
| _process_remainder_and_relation_string(related_models: Union[Dict, List], current_relation_str: Optional[str], related: str) -> Tuple[str, Optional[Union[Dict, List]]]
|
||||||
|
```
|
||||||
|
|
||||||
|
Process remainder models and relation string
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `related_models (Union[Dict, List])`: list or dict of related models
|
||||||
|
- `current_relation_str (Optional[str])`: current relation string
|
||||||
|
- `related (str)`: name of the relation
|
||||||
|
|
||||||
|
<a name="models.model_row.ModelRow._populate_through_instance"></a>
|
||||||
|
#### \_populate\_through\_instance
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @classmethod
|
| @classmethod
|
||||||
| populate_through_instance(cls, row: sqlalchemy.engine.ResultProxy, through_name: str, related: str, excludable: ExcludableItems) -> "ModelRow"
|
| _populate_through_instance(cls, row: sqlalchemy.engine.ResultProxy, item: Dict, related: str, excludable: ExcludableItems, child: "Model", proxy_source_model: Optional[Type["Model"]]) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Populates the through model on reverse side of current query.
|
||||||
|
Normally it's child class, unless the query is from queryset.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `row (sqlalchemy.engine.ResultProxy)`: row from db result
|
||||||
|
- `item (Dict)`: parent item dict
|
||||||
|
- `related (str)`: current relation name
|
||||||
|
- `excludable (ExcludableItems)`: structure of fields to include and exclude
|
||||||
|
- `child ("Model")`: child item of parent
|
||||||
|
- `proxy_source_model (Type["Model"])`: source model from which querysetproxy is constructed
|
||||||
|
|
||||||
|
<a name="models.model_row.ModelRow._create_through_instance"></a>
|
||||||
|
#### \_create\_through\_instance
|
||||||
|
|
||||||
|
```python
|
||||||
|
| @classmethod
|
||||||
|
| _create_through_instance(cls, row: sqlalchemy.engine.ResultProxy, through_name: str, related: str, excludable: ExcludableItems) -> "ModelRow"
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialize the through model from db row.
|
Initialize the through model from db row.
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class Model(ModelRow)
|
|||||||
#### upsert
|
#### upsert
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async upsert(**kwargs: Any) -> "Model"
|
| async upsert(**kwargs: Any) -> T
|
||||||
```
|
```
|
||||||
|
|
||||||
Performs either a save or an update depending on the presence of the pk.
|
Performs either a save or an update depending on the presence of the pk.
|
||||||
@ -31,7 +31,7 @@ For save kwargs are ignored, used only in update if provided.
|
|||||||
#### save
|
#### save
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async save() -> "Model"
|
| async save() -> T
|
||||||
```
|
```
|
||||||
|
|
||||||
Performs a save of given Model instance.
|
Performs a save of given Model instance.
|
||||||
@ -60,7 +60,7 @@ Sets model save status to True.
|
|||||||
#### save\_related
|
#### save\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async save_related(follow: bool = False, visited: Set = None, update_count: int = 0) -> int
|
| async save_related(follow: bool = False, save_all: bool = False, relation_map: Dict = None, exclude: Union[Set, Dict] = None, update_count: int = 0, previous_model: "Model" = None, relation_field: Optional["ForeignKeyField"] = None) -> int
|
||||||
```
|
```
|
||||||
|
|
||||||
Triggers a upsert method on all related models
|
Triggers a upsert method on all related models
|
||||||
@ -79,10 +79,14 @@ Nested relations of those kind need to be persisted manually.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
|
- `relation_field (Optional[ForeignKeyField])`: field with relation leading to this model
|
||||||
|
- `previous_model (Model)`: previous model from which method came
|
||||||
|
- `exclude (Union[Set, Dict])`: items to exclude during saving of relations
|
||||||
|
- `relation_map (Dict)`: map of relations to follow
|
||||||
|
- `save_all (bool)`: flag if all models should be saved or only not saved ones
|
||||||
- `follow (bool)`: flag to trigger deep save -
|
- `follow (bool)`: flag to trigger deep save -
|
||||||
by default only directly related models are saved
|
by default only directly related models are saved
|
||||||
with follow=True also related models of related models are saved
|
with follow=True also related models of related models are saved
|
||||||
- `visited (Set)`: internal parameter for recursive calls - already visited models
|
|
||||||
- `update_count (int)`: internal parameter for recursive calls -
|
- `update_count (int)`: internal parameter for recursive calls -
|
||||||
number of updated instances
|
number of updated instances
|
||||||
|
|
||||||
@ -90,36 +94,11 @@ number of updated instances
|
|||||||
|
|
||||||
`(int)`: number of updated/saved models
|
`(int)`: number of updated/saved models
|
||||||
|
|
||||||
<a name="models.model.Model._update_and_follow"></a>
|
|
||||||
#### \_update\_and\_follow
|
|
||||||
|
|
||||||
```python
|
|
||||||
| @staticmethod
|
|
||||||
| async _update_and_follow(rel: "Model", follow: bool, visited: Set, update_count: int) -> Tuple[int, Set]
|
|
||||||
```
|
|
||||||
|
|
||||||
Internal method used in save_related to follow related models and update numbers
|
|
||||||
of updated related instances.
|
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `rel (Model)`: Model to follow
|
|
||||||
- `follow (bool)`: flag to trigger deep save -
|
|
||||||
by default only directly related models are saved
|
|
||||||
with follow=True also related models of related models are saved
|
|
||||||
- `visited (Set)`: internal parameter for recursive calls - already visited models
|
|
||||||
- `update_count (int)`: internal parameter for recursive calls -
|
|
||||||
number of updated instances
|
|
||||||
|
|
||||||
**Returns**:
|
|
||||||
|
|
||||||
`(Tuple[int, Set])`: tuple of update count and visited
|
|
||||||
|
|
||||||
<a name="models.model.Model.update"></a>
|
<a name="models.model.Model.update"></a>
|
||||||
#### update
|
#### update
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async update(**kwargs: Any) -> "Model"
|
| async update(_columns: List[str] = None, **kwargs: Any) -> T
|
||||||
```
|
```
|
||||||
|
|
||||||
Performs update of Model instance in the database.
|
Performs update of Model instance in the database.
|
||||||
@ -129,14 +108,15 @@ Sends pre_update and post_update signals.
|
|||||||
|
|
||||||
Sets model save status to True.
|
Sets model save status to True.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `_columns (List)`: list of columns to update, if None all are updated
|
||||||
|
- `kwargs (Any)`: list of fields to update as field=value pairs
|
||||||
|
|
||||||
**Raises**:
|
**Raises**:
|
||||||
|
|
||||||
- `ModelPersistenceError`: If the pk column is not set
|
- `ModelPersistenceError`: If the pk column is not set
|
||||||
|
|
||||||
**Arguments**:
|
|
||||||
|
|
||||||
- `kwargs (Any)`: list of fields to update as field=value pairs
|
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
`(Model)`: updated Model
|
`(Model)`: updated Model
|
||||||
@ -166,7 +146,7 @@ or update and the Model will be saved in database again.
|
|||||||
#### load
|
#### load
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async load() -> "Model"
|
| async load() -> T
|
||||||
```
|
```
|
||||||
|
|
||||||
Allow to refresh existing Models fields from database.
|
Allow to refresh existing Models fields from database.
|
||||||
@ -185,7 +165,7 @@ Does NOT refresh the related models fields if they were loaded before.
|
|||||||
#### load\_all
|
#### load\_all
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async load_all(follow: bool = False, exclude: Union[List, str, Set, Dict] = None) -> "Model"
|
| async load_all(follow: bool = False, exclude: Union[List, str, Set, Dict] = None, order_by: Union[List, str] = None) -> T
|
||||||
```
|
```
|
||||||
|
|
||||||
Allow to refresh existing Models fields from database.
|
Allow to refresh existing Models fields from database.
|
||||||
@ -203,17 +183,18 @@ follow them inside. So Model A -> Model B -> Model C -> Model A -> Model X
|
|||||||
will load second Model A but will never follow into Model X.
|
will load second Model A but will never follow into Model X.
|
||||||
Nested relations of those kind need to be loaded manually.
|
Nested relations of those kind need to be loaded manually.
|
||||||
|
|
||||||
**Raises**:
|
|
||||||
|
|
||||||
- `NoMatch`: If given pk is not found in database.
|
|
||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `exclude ()`:
|
- `order_by (Union[List, str])`: columns by which models should be sorted
|
||||||
|
- `exclude (Union[List, str, Set, Dict])`: related models to exclude
|
||||||
- `follow (bool)`: flag to trigger deep save -
|
- `follow (bool)`: flag to trigger deep save -
|
||||||
by default only directly related models are saved
|
by default only directly related models are saved
|
||||||
with follow=True also related models of related models are saved
|
with follow=True also related models of related models are saved
|
||||||
|
|
||||||
|
**Raises**:
|
||||||
|
|
||||||
|
- `NoMatch`: If given pk is not found in database.
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
`(Model)`: reloaded Model
|
`(Model)`: reloaded Model
|
||||||
|
|||||||
@ -364,7 +364,7 @@ Returns related field names applying on them include and exclude set.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @staticmethod
|
| @staticmethod
|
||||||
| _extract_nested_models_from_list(models: MutableSequence, include: Union[Set, Dict, None], exclude: Union[Set, Dict, None]) -> List
|
| _extract_nested_models_from_list(relation_map: Dict, models: MutableSequence, include: Union[Set, Dict, None], exclude: Union[Set, Dict, None]) -> List
|
||||||
```
|
```
|
||||||
|
|
||||||
Converts list of models into list of dictionaries.
|
Converts list of models into list of dictionaries.
|
||||||
@ -383,7 +383,7 @@ Converts list of models into list of dictionaries.
|
|||||||
#### \_skip\_ellipsis
|
#### \_skip\_ellipsis
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _skip_ellipsis(items: Union[Set, Dict, None], key: str) -> Union[Set, Dict, None]
|
| _skip_ellipsis(items: Union[Set, Dict, None], key: str, default_return: Any = None) -> Union[Set, Dict, None]
|
||||||
```
|
```
|
||||||
|
|
||||||
Helper to traverse the include/exclude dictionaries.
|
Helper to traverse the include/exclude dictionaries.
|
||||||
@ -399,11 +399,25 @@ and not the actual set/dict with fields names.
|
|||||||
|
|
||||||
`(Union[Set, Dict, None])`: nested value of the items
|
`(Union[Set, Dict, None])`: nested value of the items
|
||||||
|
|
||||||
|
<a name="models.newbasemodel.NewBaseModel._convert_all"></a>
|
||||||
|
#### \_convert\_all
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _convert_all(items: Union[Set, Dict, None]) -> Union[Set, Dict, None]
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper to convert __all__ pydantic special index to ormar which does not
|
||||||
|
support index based exclusions.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `items (Union[Set, Dict, None])`: current include/exclude value
|
||||||
|
|
||||||
<a name="models.newbasemodel.NewBaseModel._extract_nested_models"></a>
|
<a name="models.newbasemodel.NewBaseModel._extract_nested_models"></a>
|
||||||
#### \_extract\_nested\_models
|
#### \_extract\_nested\_models
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _extract_nested_models(nested: bool, dict_instance: Dict, include: Optional[Dict], exclude: Optional[Dict]) -> Dict
|
| _extract_nested_models(relation_map: Dict, dict_instance: Dict, include: Optional[Dict], exclude: Optional[Dict]) -> Dict
|
||||||
```
|
```
|
||||||
|
|
||||||
Traverse nested models and converts them into dictionaries.
|
Traverse nested models and converts them into dictionaries.
|
||||||
@ -424,7 +438,7 @@ Calls itself recursively if needed.
|
|||||||
#### dict
|
#### dict
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| dict(*, include: Union[Set, Dict] = None, exclude: Union[Set, Dict] = None, by_alias: bool = False, skip_defaults: bool = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, nested: bool = False) -> "DictStrAny"
|
| dict(*, include: Union[Set, Dict] = None, exclude: Union[Set, Dict] = None, by_alias: bool = False, skip_defaults: bool = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, relation_map: Dict = None) -> "DictStrAny"
|
||||||
```
|
```
|
||||||
|
|
||||||
Generate a dictionary representation of the model,
|
Generate a dictionary representation of the model,
|
||||||
@ -443,7 +457,7 @@ Additionally fields decorated with @property_field are also added.
|
|||||||
- `exclude_unset (bool)`: flag to exclude not set values - passed to pydantic
|
- `exclude_unset (bool)`: flag to exclude not set values - passed to pydantic
|
||||||
- `exclude_defaults (bool)`: flag to exclude default values - passed to pydantic
|
- `exclude_defaults (bool)`: flag to exclude default values - passed to pydantic
|
||||||
- `exclude_none (bool)`: flag to exclude None values - passed to pydantic
|
- `exclude_none (bool)`: flag to exclude None values - passed to pydantic
|
||||||
- `nested (bool)`: flag if the current model is nested
|
- `relation_map (Dict)`: map of the relations to follow to avoid circural deps
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
@ -536,14 +550,14 @@ That includes own non-relational fields ang foreign key fields.
|
|||||||
#### get\_relation\_model\_id
|
#### get\_relation\_model\_id
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| get_relation_model_id(target_field: Type["BaseField"]) -> Optional[int]
|
| get_relation_model_id(target_field: "BaseField") -> Optional[int]
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns an id of the relation side model to use in prefetch query.
|
Returns an id of the relation side model to use in prefetch query.
|
||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `target_field (Type["BaseField"])`: field with relation definition
|
- `target_field ("BaseField")`: field with relation definition
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
|
|||||||
78
docs/api/models/traversible.md
Normal file
78
docs/api/models/traversible.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<a name="models.traversible"></a>
|
||||||
|
# models.traversible
|
||||||
|
|
||||||
|
<a name="models.traversible.NodeList"></a>
|
||||||
|
## NodeList Objects
|
||||||
|
|
||||||
|
```python
|
||||||
|
class NodeList()
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper class that helps with iterating nested models
|
||||||
|
|
||||||
|
<a name="models.traversible.NodeList.add"></a>
|
||||||
|
#### add
|
||||||
|
|
||||||
|
```python
|
||||||
|
| add(node_class: Type["RelationMixin"], relation_name: str = None, parent_node: "Node" = None) -> "Node"
|
||||||
|
```
|
||||||
|
|
||||||
|
Adds new Node or returns the existing one
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `node_class (ormar.models.metaclass.ModelMetaclass)`: Model in current node
|
||||||
|
- `relation_name (str)`: name of the current relation
|
||||||
|
- `parent_node (Optional[Node])`: parent node
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Node)`: returns new or already existing node
|
||||||
|
|
||||||
|
<a name="models.traversible.NodeList.find"></a>
|
||||||
|
#### find
|
||||||
|
|
||||||
|
```python
|
||||||
|
| find(node_class: Type["RelationMixin"], relation_name: Optional[str] = None, parent_node: "Node" = None) -> Optional["Node"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Searches for existing node with given parameters
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `node_class (ormar.models.metaclass.ModelMetaclass)`: Model in current node
|
||||||
|
- `relation_name (str)`: name of the current relation
|
||||||
|
- `parent_node (Optional[Node])`: parent node
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Optional[Node])`: returns already existing node or None
|
||||||
|
|
||||||
|
<a name="models.traversible.Node"></a>
|
||||||
|
## Node Objects
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Node()
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="models.traversible.Node.visited"></a>
|
||||||
|
#### visited
|
||||||
|
|
||||||
|
```python
|
||||||
|
| visited(relation_name: str) -> bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Checks if given relation was already visited.
|
||||||
|
|
||||||
|
Relation was visited if it's name is in current node children.
|
||||||
|
|
||||||
|
Relation was visited if one of the parent node had the same Model class
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `relation_name (str)`: name of relation
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(bool)`: result of the check
|
||||||
|
|
||||||
@ -1,6 +1,115 @@
|
|||||||
<a name="queryset.clause"></a>
|
<a name="queryset.clause"></a>
|
||||||
# queryset.clause
|
# queryset.clause
|
||||||
|
|
||||||
|
<a name="queryset.clause.FilterGroup"></a>
|
||||||
|
## FilterGroup Objects
|
||||||
|
|
||||||
|
```python
|
||||||
|
class FilterGroup()
|
||||||
|
```
|
||||||
|
|
||||||
|
Filter groups are used in complex queries condition to group and and or
|
||||||
|
clauses in where condition
|
||||||
|
|
||||||
|
<a name="queryset.clause.FilterGroup.resolve"></a>
|
||||||
|
#### resolve
|
||||||
|
|
||||||
|
```python
|
||||||
|
| resolve(model_cls: Type["Model"], select_related: List = None, filter_clauses: List = None) -> Tuple[List[FilterAction], List[str]]
|
||||||
|
```
|
||||||
|
|
||||||
|
Resolves the FilterGroups actions to use proper target model, replace
|
||||||
|
complex relation prefixes if needed and nested groups also resolved.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `model_cls (Type["Model"])`: model from which the query is run
|
||||||
|
- `select_related (List[str])`: list of models to join
|
||||||
|
- `filter_clauses (List[FilterAction])`: list of filter conditions
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Tuple[List[FilterAction], List[str]])`: list of filter conditions and select_related list
|
||||||
|
|
||||||
|
<a name="queryset.clause.FilterGroup._iter"></a>
|
||||||
|
#### \_iter
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _iter() -> Generator
|
||||||
|
```
|
||||||
|
|
||||||
|
Iterates all actions in a tree
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Generator)`: generator yielding from own actions and nested groups
|
||||||
|
|
||||||
|
<a name="queryset.clause.FilterGroup._get_text_clauses"></a>
|
||||||
|
#### \_get\_text\_clauses
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _get_text_clauses() -> List[sqlalchemy.sql.expression.TextClause]
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper to return list of text queries from actions and nested groups
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(List[sqlalchemy.sql.elements.TextClause])`: list of text queries from actions and nested groups
|
||||||
|
|
||||||
|
<a name="queryset.clause.FilterGroup.get_text_clause"></a>
|
||||||
|
#### get\_text\_clause
|
||||||
|
|
||||||
|
```python
|
||||||
|
| get_text_clause() -> sqlalchemy.sql.expression.TextClause
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns all own actions and nested groups conditions compiled and joined
|
||||||
|
inside parentheses.
|
||||||
|
Escapes characters if it's required.
|
||||||
|
Substitutes values of the models if value is a ormar Model with its pk value.
|
||||||
|
Compiles the clause.
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(sqlalchemy.sql.elements.TextClause)`: complied and escaped clause
|
||||||
|
|
||||||
|
<a name="queryset.clause.or_"></a>
|
||||||
|
#### or\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
or_(*args: FilterGroup, **kwargs: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
Construct or filter from nested groups and keyword arguments
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `args (Tuple[FilterGroup])`: nested filter groups
|
||||||
|
- `kwargs (Any)`: fields names and proper value types
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup ready to be resolved
|
||||||
|
|
||||||
|
<a name="queryset.clause.and_"></a>
|
||||||
|
#### and\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
and_(*args: FilterGroup, **kwargs: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
Construct and filter from nested groups and keyword arguments
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `args (Tuple[FilterGroup])`: nested filter groups
|
||||||
|
- `kwargs (Any)`: fields names and proper value types
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup ready to be resolved
|
||||||
|
|
||||||
<a name="queryset.clause.QueryClause"></a>
|
<a name="queryset.clause.QueryClause"></a>
|
||||||
## QueryClause Objects
|
## QueryClause Objects
|
||||||
|
|
||||||
@ -14,7 +123,7 @@ Constructs FilterActions from strings passed as arguments
|
|||||||
#### prepare\_filter
|
#### prepare\_filter
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| prepare_filter(**kwargs: Any) -> Tuple[List[FilterAction], List[str]]
|
| prepare_filter(_own_only: bool = False, **kwargs: Any) -> Tuple[List[FilterAction], List[str]]
|
||||||
```
|
```
|
||||||
|
|
||||||
Main external access point that processes the clauses into sqlalchemy text
|
Main external access point that processes the clauses into sqlalchemy text
|
||||||
@ -23,6 +132,7 @@ mentioned in select_related strings but not included in select_related.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
|
- `_own_only ()`:
|
||||||
- `kwargs (Any)`: key, value pair with column names and values
|
- `kwargs (Any)`: key, value pair with column names and values
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
@ -33,7 +143,7 @@ mentioned in select_related strings but not included in select_related.
|
|||||||
#### \_populate\_filter\_clauses
|
#### \_populate\_filter\_clauses
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _populate_filter_clauses(**kwargs: Any) -> Tuple[List[FilterAction], List[str]]
|
| _populate_filter_clauses(_own_only: bool, **kwargs: Any) -> Tuple[List[FilterAction], List[str]]
|
||||||
```
|
```
|
||||||
|
|
||||||
Iterates all clauses and extracts used operator and field from related
|
Iterates all clauses and extracts used operator and field from related
|
||||||
@ -104,3 +214,16 @@ present in alias_manager.
|
|||||||
|
|
||||||
`(List[FilterAction])`: list of actions with aliases changed if needed
|
`(List[FilterAction])`: list of actions with aliases changed if needed
|
||||||
|
|
||||||
|
<a name="queryset.clause.QueryClause._verify_prefix_and_switch"></a>
|
||||||
|
#### \_verify\_prefix\_and\_switch
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _verify_prefix_and_switch(action: "FilterAction") -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper to switch prefix to complex relation one if required
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `action (ormar.queryset.actions.filter_action.FilterAction)`: action to switch prefix in
|
||||||
|
|
||||||
|
|||||||
359
docs/api/query-set/field-accessor.md
Normal file
359
docs/api/query-set/field-accessor.md
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
<a name="queryset.field_accessor"></a>
|
||||||
|
# queryset.field\_accessor
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor"></a>
|
||||||
|
## FieldAccessor Objects
|
||||||
|
|
||||||
|
```python
|
||||||
|
class FieldAccessor()
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper to access ormar fields directly from Model class also for nested
|
||||||
|
models attributes.
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__bool__"></a>
|
||||||
|
#### \_\_bool\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __bool__() -> bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Hack to avoid pydantic name check from parent model, returns false
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(bool)`: False
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__getattr__"></a>
|
||||||
|
#### \_\_getattr\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __getattr__(item: str) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Accessor return new accessor for each field and nested models.
|
||||||
|
Thanks to that operator overload is possible to use in filter.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `item (str)`: attribute name
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.field_accessor.FieldAccessor)`: FieldAccessor for field or nested model
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__eq__"></a>
|
||||||
|
#### \_\_eq\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __eq__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column = <VALUE>`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__ge__"></a>
|
||||||
|
#### \_\_ge\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __ge__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column >= <VALUE>`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__gt__"></a>
|
||||||
|
#### \_\_gt\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __gt__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column > <VALUE>`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__le__"></a>
|
||||||
|
#### \_\_le\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __le__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column <= <VALUE>`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__lt__"></a>
|
||||||
|
#### \_\_lt\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __lt__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column < <VALUE>`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__mod__"></a>
|
||||||
|
#### \_\_mod\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __mod__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column LIKE '%<VALUE>%'`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__lshift__"></a>
|
||||||
|
#### \_\_lshift\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __lshift__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column IN (<VALUE1>, <VALUE2>,...)`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.__rshift__"></a>
|
||||||
|
#### \_\_rshift\_\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| __rshift__(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
overloaded to work as sql `column IS NULL`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.in_"></a>
|
||||||
|
#### in\_
|
||||||
|
|
||||||
|
```python
|
||||||
|
| in_(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column IN (<VALUE1>, <VALUE2>,...)`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.iexact"></a>
|
||||||
|
#### iexact
|
||||||
|
|
||||||
|
```python
|
||||||
|
| iexact(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column = <VALUE>` case-insensitive
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.contains"></a>
|
||||||
|
#### contains
|
||||||
|
|
||||||
|
```python
|
||||||
|
| contains(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column LIKE '%<VALUE>%'`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.icontains"></a>
|
||||||
|
#### icontains
|
||||||
|
|
||||||
|
```python
|
||||||
|
| icontains(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column LIKE '%<VALUE>%'` case-insensitive
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.startswith"></a>
|
||||||
|
#### startswith
|
||||||
|
|
||||||
|
```python
|
||||||
|
| startswith(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column LIKE '<VALUE>%'`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.istartswith"></a>
|
||||||
|
#### istartswith
|
||||||
|
|
||||||
|
```python
|
||||||
|
| istartswith(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column LIKE '%<VALUE>'` case-insensitive
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.endswith"></a>
|
||||||
|
#### endswith
|
||||||
|
|
||||||
|
```python
|
||||||
|
| endswith(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column LIKE '%<VALUE>'`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.iendswith"></a>
|
||||||
|
#### iendswith
|
||||||
|
|
||||||
|
```python
|
||||||
|
| iendswith(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column LIKE '%<VALUE>'` case-insensitive
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.isnull"></a>
|
||||||
|
#### isnull
|
||||||
|
|
||||||
|
```python
|
||||||
|
| isnull(other: Any) -> FilterGroup
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column IS NULL` or `IS NOT NULL`
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `other (str)`: value to check agains operator
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.clause.FilterGroup)`: FilterGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.asc"></a>
|
||||||
|
#### asc
|
||||||
|
|
||||||
|
```python
|
||||||
|
| asc() -> OrderAction
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column asc`
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.actions.OrderGroup)`: OrderGroup for operator
|
||||||
|
|
||||||
|
<a name="queryset.field_accessor.FieldAccessor.desc"></a>
|
||||||
|
#### desc
|
||||||
|
|
||||||
|
```python
|
||||||
|
| desc() -> OrderAction
|
||||||
|
```
|
||||||
|
|
||||||
|
works as sql `column desc`
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(ormar.queryset.actions.OrderGroup)`: OrderGroup for operator
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ Shortcut for ormar's model AliasManager stored on Meta.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @property
|
| @property
|
||||||
| to_table() -> str
|
| to_table() -> sqlalchemy.Table
|
||||||
```
|
```
|
||||||
|
|
||||||
Shortcut to table name of the next model
|
Shortcut to table name of the next model
|
||||||
@ -172,6 +172,36 @@ Updates the used aliases list directly.
|
|||||||
|
|
||||||
Process order_by causes for non m2m relations.
|
Process order_by causes for non m2m relations.
|
||||||
|
|
||||||
|
<a name="queryset.join.SqlJoin._verify_allowed_order_field"></a>
|
||||||
|
#### \_verify\_allowed\_order\_field
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _verify_allowed_order_field(order_by: str) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Verifies if proper field string is used.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `order_by (str)`: string with order by definition
|
||||||
|
|
||||||
|
<a name="queryset.join.SqlJoin._get_alias_and_model"></a>
|
||||||
|
#### \_get\_alias\_and\_model
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _get_alias_and_model(order_by: str) -> Tuple[str, Type["Model"]]
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns proper model and alias to be applied in the clause.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `order_by (str)`: string with order by definition
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Tuple[str, Type["Model"]])`: alias and model to be used in clause
|
||||||
|
|
||||||
<a name="queryset.join.SqlJoin._get_order_bys"></a>
|
<a name="queryset.join.SqlJoin._get_order_bys"></a>
|
||||||
#### \_get\_order\_bys
|
#### \_get\_order\_bys
|
||||||
|
|
||||||
|
|||||||
@ -241,7 +241,7 @@ Calls itself recurrently to extract deeper nested relations of related model.
|
|||||||
#### \_run\_prefetch\_query
|
#### \_run\_prefetch\_query
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async _run_prefetch_query(target_field: Type["BaseField"], excludable: "ExcludableItems", filter_clauses: List, related_field_name: str) -> Tuple[str, str, List]
|
| async _run_prefetch_query(target_field: "BaseField", excludable: "ExcludableItems", filter_clauses: List, related_field_name: str) -> Tuple[str, str, List]
|
||||||
```
|
```
|
||||||
|
|
||||||
Actually runs the queries against the database and populates the raw response
|
Actually runs the queries against the database and populates the raw response
|
||||||
@ -252,7 +252,7 @@ models.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `target_field (Type["BaseField"])`: ormar field with relation definition
|
- `target_field ("BaseField")`: ormar field with relation definition
|
||||||
- `filter_clauses (List[sqlalchemy.sql.elements.TextClause])`: list of clauses, actually one clause with ids of relation
|
- `filter_clauses (List[sqlalchemy.sql.elements.TextClause])`: list of clauses, actually one clause with ids of relation
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
@ -283,14 +283,14 @@ deeper on related model and already loaded in select related query.
|
|||||||
#### \_update\_already\_loaded\_rows
|
#### \_update\_already\_loaded\_rows
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _update_already_loaded_rows(target_field: Type["BaseField"], prefetch_dict: Dict, orders_by: Dict) -> None
|
| _update_already_loaded_rows(target_field: "BaseField", prefetch_dict: Dict, orders_by: Dict) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates models that are already loaded, usually children of children.
|
Updates models that are already loaded, usually children of children.
|
||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `target_field (Type["BaseField"])`: ormar field with relation definition
|
- `target_field ("BaseField")`: ormar field with relation definition
|
||||||
- `prefetch_dict (Dict)`: dictionaries of related models to prefetch
|
- `prefetch_dict (Dict)`: dictionaries of related models to prefetch
|
||||||
- `orders_by (Dict)`: dictionary of order by clauses by model
|
- `orders_by (Dict)`: dictionary of order by clauses by model
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ Updates models that are already loaded, usually children of children.
|
|||||||
#### \_populate\_rows
|
#### \_populate\_rows
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _populate_rows(rows: List, target_field: Type["ForeignKeyField"], parent_model: Type["Model"], table_prefix: str, exclude_prefix: str, excludable: "ExcludableItems", prefetch_dict: Dict, orders_by: Dict) -> None
|
| _populate_rows(rows: List, target_field: "ForeignKeyField", parent_model: Type["Model"], table_prefix: str, exclude_prefix: str, excludable: "ExcludableItems", prefetch_dict: Dict, orders_by: Dict) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Instantiates children models extracted from given relation.
|
Instantiates children models extracted from given relation.
|
||||||
@ -314,7 +314,7 @@ and set on the parent model after sorting if needed.
|
|||||||
|
|
||||||
- `excludable (ExcludableItems)`: structure of fields to include and exclude
|
- `excludable (ExcludableItems)`: structure of fields to include and exclude
|
||||||
- `rows (List[sqlalchemy.engine.result.RowProxy])`: raw sql response from the prefetch query
|
- `rows (List[sqlalchemy.engine.result.RowProxy])`: raw sql response from the prefetch query
|
||||||
- `target_field (Type["BaseField"])`: field with relation definition from parent model
|
- `target_field ("BaseField")`: field with relation definition from parent model
|
||||||
- `parent_model (Type[Model])`: model with relation definition
|
- `parent_model (Type[Model])`: model with relation definition
|
||||||
- `table_prefix (str)`: prefix of the target table from current relation
|
- `table_prefix (str)`: prefix of the target table from current relation
|
||||||
- `prefetch_dict (Dict)`: dictionaries of related models to prefetch
|
- `prefetch_dict (Dict)`: dictionaries of related models to prefetch
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
## QuerySet Objects
|
## QuerySet Objects
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class QuerySet()
|
class QuerySet(Generic[T])
|
||||||
```
|
```
|
||||||
|
|
||||||
Main class to perform database queries, exposed on each model as objects attribute.
|
Main class to perform database queries, exposed on each model as objects attribute.
|
||||||
@ -29,7 +29,7 @@ Shortcut to model class Meta set on QuerySet model.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @property
|
| @property
|
||||||
| model() -> Type["Model"]
|
| model() -> Type["T"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Shortcut to model class set on QuerySet.
|
Shortcut to model class set on QuerySet.
|
||||||
@ -52,7 +52,7 @@ all not passed params are taken from current values.
|
|||||||
#### \_prefetch\_related\_models
|
#### \_prefetch\_related\_models
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async _prefetch_related_models(models: Sequence[Optional["Model"]], rows: List) -> Sequence[Optional["Model"]]
|
| async _prefetch_related_models(models: List[Optional["T"]], rows: List) -> List[Optional["T"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
Performs prefetch query for selected models names.
|
Performs prefetch query for selected models names.
|
||||||
@ -70,7 +70,7 @@ Performs prefetch query for selected models names.
|
|||||||
#### \_process\_query\_result\_rows
|
#### \_process\_query\_result\_rows
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _process_query_result_rows(rows: List) -> Sequence[Optional["Model"]]
|
| _process_query_result_rows(rows: List) -> List[Optional["T"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
Process database rows and initialize ormar Model from each of the rows.
|
Process database rows and initialize ormar Model from each of the rows.
|
||||||
@ -83,12 +83,29 @@ Process database rows and initialize ormar Model from each of the rows.
|
|||||||
|
|
||||||
`(List[Model])`: list of models
|
`(List[Model])`: list of models
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet._resolve_filter_groups"></a>
|
||||||
|
#### \_resolve\_filter\_groups
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _resolve_filter_groups(groups: Any) -> Tuple[List[FilterGroup], List[str]]
|
||||||
|
```
|
||||||
|
|
||||||
|
Resolves filter groups to populate FilterAction params in group tree.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `groups (Any)`: tuple of FilterGroups
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Tuple[List[FilterGroup], List[str]])`: list of resolver groups
|
||||||
|
|
||||||
<a name="queryset.queryset.QuerySet.check_single_result_rows_count"></a>
|
<a name="queryset.queryset.QuerySet.check_single_result_rows_count"></a>
|
||||||
#### check\_single\_result\_rows\_count
|
#### check\_single\_result\_rows\_count
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| @staticmethod
|
| @staticmethod
|
||||||
| check_single_result_rows_count(rows: Sequence[Optional["Model"]]) -> None
|
| check_single_result_rows_count(rows: Sequence[Optional["T"]]) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Verifies if the result has one and only one row.
|
Verifies if the result has one and only one row.
|
||||||
@ -149,7 +166,7 @@ If any of the params is not passed the QuerySet own value is used.
|
|||||||
#### filter
|
#### filter
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| filter(_exclude: bool = False, **kwargs: Any) -> "QuerySet"
|
| filter(*args: Any, *, _exclude: bool = False, **kwargs: Any) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Allows you to filter by any `Model` attribute/field
|
Allows you to filter by any `Model` attribute/field
|
||||||
@ -162,6 +179,8 @@ You can use special filter suffix to change the filter operands:
|
|||||||
* contains - like `album__name__contains='Mal'` (sql like)
|
* contains - like `album__name__contains='Mal'` (sql like)
|
||||||
* icontains - like `album__name__icontains='mal'` (sql like case insensitive)
|
* icontains - like `album__name__icontains='mal'` (sql like case insensitive)
|
||||||
* in - like `album__name__in=['Malibu', 'Barclay']` (sql in)
|
* in - like `album__name__in=['Malibu', 'Barclay']` (sql in)
|
||||||
|
* isnull - like `album__name__isnull=True` (sql is null)
|
||||||
|
(isnotnull `album__name__isnull=False` (sql is not null))
|
||||||
* gt - like `position__gt=3` (sql >)
|
* gt - like `position__gt=3` (sql >)
|
||||||
* gte - like `position__gte=3` (sql >=)
|
* gte - like `position__gte=3` (sql >=)
|
||||||
* lt - like `position__lt=3` (sql <)
|
* lt - like `position__lt=3` (sql <)
|
||||||
@ -184,7 +203,7 @@ You can use special filter suffix to change the filter operands:
|
|||||||
#### exclude
|
#### exclude
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| exclude(**kwargs: Any) -> "QuerySet"
|
| exclude(*args: Any, **kwargs: Any) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Works exactly the same as filter and all modifiers (suffixes) are the same,
|
Works exactly the same as filter and all modifiers (suffixes) are the same,
|
||||||
@ -211,7 +230,7 @@ becomes a union of conditions.
|
|||||||
#### select\_related
|
#### select\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| select_related(related: Union[List, str]) -> "QuerySet"
|
| select_related(related: Union[List, str]) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Allows to prefetch related models during the same query.
|
Allows to prefetch related models during the same query.
|
||||||
@ -232,11 +251,40 @@ To chain related `Models` relation use double underscores between names.
|
|||||||
|
|
||||||
`(QuerySet)`: QuerySet
|
`(QuerySet)`: QuerySet
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet.select_all"></a>
|
||||||
|
#### select\_all
|
||||||
|
|
||||||
|
```python
|
||||||
|
| select_all(follow: bool = False) -> "QuerySet[T]"
|
||||||
|
```
|
||||||
|
|
||||||
|
By default adds only directly related models.
|
||||||
|
|
||||||
|
If follow=True is set it adds also related models of related models.
|
||||||
|
|
||||||
|
To not get stuck in an infinite loop as related models also keep a relation
|
||||||
|
to parent model visited models set is kept.
|
||||||
|
|
||||||
|
That way already visited models that are nested are loaded, but the load do not
|
||||||
|
follow them inside. So Model A -> Model B -> Model C -> Model A -> Model X
|
||||||
|
will load second Model A but will never follow into Model X.
|
||||||
|
Nested relations of those kind need to be loaded manually.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `follow (bool)`: flag to trigger deep save -
|
||||||
|
by default only directly related models are saved
|
||||||
|
with follow=True also related models of related models are saved
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Model)`: reloaded Model
|
||||||
|
|
||||||
<a name="queryset.queryset.QuerySet.prefetch_related"></a>
|
<a name="queryset.queryset.QuerySet.prefetch_related"></a>
|
||||||
#### prefetch\_related
|
#### prefetch\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| prefetch_related(related: Union[List, str]) -> "QuerySet"
|
| prefetch_related(related: Union[List, str]) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Allows to prefetch related models during query - but opposite to
|
Allows to prefetch related models during query - but opposite to
|
||||||
@ -262,7 +310,7 @@ To chain related `Models` relation use double underscores between names.
|
|||||||
#### fields
|
#### fields
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| fields(columns: Union[List, str, Set, Dict], _is_exclude: bool = False) -> "QuerySet"
|
| fields(columns: Union[List, str, Set, Dict], _is_exclude: bool = False) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
With `fields()` you can select subset of model columns to limit the data load.
|
With `fields()` you can select subset of model columns to limit the data load.
|
||||||
@ -314,7 +362,7 @@ To include whole nested model specify model related field name and ellipsis.
|
|||||||
#### exclude\_fields
|
#### exclude\_fields
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| exclude_fields(columns: Union[List, str, Set, Dict]) -> "QuerySet"
|
| exclude_fields(columns: Union[List, str, Set, Dict]) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
With `exclude_fields()` you can select subset of model columns that will
|
With `exclude_fields()` you can select subset of model columns that will
|
||||||
@ -349,7 +397,7 @@ if explicitly excluded.
|
|||||||
#### order\_by
|
#### order\_by
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| order_by(columns: Union[List, str]) -> "QuerySet"
|
| order_by(columns: Union[List, str, OrderAction]) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
With `order_by()` you can order the results from database based on your
|
With `order_by()` you can order the results from database based on your
|
||||||
@ -413,6 +461,62 @@ Returns number of rows matching the given criteria
|
|||||||
|
|
||||||
`(int)`: number of rows
|
`(int)`: number of rows
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet.max"></a>
|
||||||
|
#### max
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async max(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns max value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Any)`: max value of column(s)
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet.min"></a>
|
||||||
|
#### min
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async min(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns min value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Any)`: min value of column(s)
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet.sum"></a>
|
||||||
|
#### sum
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async sum(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns sum value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(int)`: sum value of columns
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet.avg"></a>
|
||||||
|
#### avg
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async avg(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns avg value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Union[int, float, List])`: avg value of columns
|
||||||
|
|
||||||
<a name="queryset.queryset.QuerySet.update"></a>
|
<a name="queryset.queryset.QuerySet.update"></a>
|
||||||
#### update
|
#### update
|
||||||
|
|
||||||
@ -438,7 +542,7 @@ each=True flag to affect whole table.
|
|||||||
#### delete
|
#### delete
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async delete(each: bool = False, **kwargs: Any) -> int
|
| async delete(*args: Any, *, each: bool = False, **kwargs: Any) -> int
|
||||||
```
|
```
|
||||||
|
|
||||||
Deletes from the model table after applying the filters from kwargs.
|
Deletes from the model table after applying the filters from kwargs.
|
||||||
@ -459,7 +563,7 @@ each=True flag to affect whole table.
|
|||||||
#### paginate
|
#### paginate
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| paginate(page: int, page_size: int = 20) -> "QuerySet"
|
| paginate(page: int, page_size: int = 20) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can paginate the result which is a combination of offset and limit clauses.
|
You can paginate the result which is a combination of offset and limit clauses.
|
||||||
@ -478,7 +582,7 @@ Limit is set to page size and offset is set to (page-1) * page_size.
|
|||||||
#### limit
|
#### limit
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| limit(limit_count: int, limit_raw_sql: bool = None) -> "QuerySet"
|
| limit(limit_count: int, limit_raw_sql: bool = None) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can limit the results to desired number of parent models.
|
You can limit the results to desired number of parent models.
|
||||||
@ -499,7 +603,7 @@ models use the `limit_raw_sql` parameter flag, and set it to `True`.
|
|||||||
#### offset
|
#### offset
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| offset(offset: int, limit_raw_sql: bool = None) -> "QuerySet"
|
| offset(offset: int, limit_raw_sql: bool = None) -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also offset the results by desired number of main models.
|
You can also offset the results by desired number of main models.
|
||||||
@ -520,7 +624,7 @@ models use the `limit_raw_sql` parameter flag, and set it to `True`.
|
|||||||
#### first
|
#### first
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async first(**kwargs: Any) -> "Model"
|
| async first(*args: Any, **kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Gets the first row from the db ordered by primary key column ascending.
|
Gets the first row from the db ordered by primary key column ascending.
|
||||||
@ -538,11 +642,34 @@ Gets the first row from the db ordered by primary key column ascending.
|
|||||||
|
|
||||||
`(Model)`: returned model
|
`(Model)`: returned model
|
||||||
|
|
||||||
|
<a name="queryset.queryset.QuerySet.get_or_none"></a>
|
||||||
|
#### get\_or\_none
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async get_or_none(*args: Any, **kwargs: Any) -> Optional["T"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Get's the first row from the db meeting the criteria set by kwargs.
|
||||||
|
|
||||||
|
If no criteria set it will return the last row in db sorted by pk.
|
||||||
|
|
||||||
|
Passing a criteria is actually calling filter(**kwargs) method described below.
|
||||||
|
|
||||||
|
If not match is found None will be returned.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `kwargs (Any)`: fields names and proper value types
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Model)`: returned model
|
||||||
|
|
||||||
<a name="queryset.queryset.QuerySet.get"></a>
|
<a name="queryset.queryset.QuerySet.get"></a>
|
||||||
#### get
|
#### get
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async get(**kwargs: Any) -> "Model"
|
| async get(*args: Any, **kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Get's the first row from the db meeting the criteria set by kwargs.
|
Get's the first row from the db meeting the criteria set by kwargs.
|
||||||
@ -568,7 +695,7 @@ Passing a criteria is actually calling filter(**kwargs) method described below.
|
|||||||
#### get\_or\_create
|
#### get\_or\_create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async get_or_create(**kwargs: Any) -> "Model"
|
| async get_or_create(*args: Any, **kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Combination of create and get methods.
|
Combination of create and get methods.
|
||||||
@ -589,7 +716,7 @@ it creates a new one with given kwargs.
|
|||||||
#### update\_or\_create
|
#### update\_or\_create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async update_or_create(**kwargs: Any) -> "Model"
|
| async update_or_create(**kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates the model, or in case there is no match in database creates a new one.
|
Updates the model, or in case there is no match in database creates a new one.
|
||||||
@ -606,7 +733,7 @@ Updates the model, or in case there is no match in database creates a new one.
|
|||||||
#### all
|
#### all
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async all(**kwargs: Any) -> Sequence[Optional["Model"]]
|
| async all(*args: Any, **kwargs: Any) -> List[Optional["T"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns all rows from a database for given model for set filter options.
|
Returns all rows from a database for given model for set filter options.
|
||||||
@ -627,7 +754,7 @@ If there are no rows meeting the criteria an empty list is returned.
|
|||||||
#### create
|
#### create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async create(**kwargs: Any) -> "Model"
|
| async create(**kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Creates the model instance, saves it in a database and returns the updates model
|
Creates the model instance, saves it in a database and returns the updates model
|
||||||
@ -647,7 +774,7 @@ The allowed kwargs are `Model` fields names and proper value types.
|
|||||||
#### bulk\_create
|
#### bulk\_create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async bulk_create(objects: List["Model"]) -> None
|
| async bulk_create(objects: List["T"]) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Performs a bulk update in one database session to speed up the process.
|
Performs a bulk update in one database session to speed up the process.
|
||||||
@ -666,7 +793,7 @@ Bulk operations do not send signals.
|
|||||||
#### bulk\_update
|
#### bulk\_update
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async bulk_update(objects: List["Model"], columns: List[str] = None) -> None
|
| async bulk_update(objects: List["T"], columns: List[str] = None) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Performs bulk update in one database session to speed up the process.
|
Performs bulk update in one database session to speed up the process.
|
||||||
|
|||||||
@ -28,6 +28,16 @@ Applies order_by queries on main model when it's used as a subquery.
|
|||||||
That way the subquery with limit and offset only on main model has proper
|
That way the subquery with limit and offset only on main model has proper
|
||||||
sorting applied and correct models are fetched.
|
sorting applied and correct models are fetched.
|
||||||
|
|
||||||
|
<a name="queryset.query.Query._apply_default_model_sorting"></a>
|
||||||
|
#### \_apply\_default\_model\_sorting
|
||||||
|
|
||||||
|
```python
|
||||||
|
| _apply_default_model_sorting() -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Applies orders_by from model Meta class (if provided), if it was not provided
|
||||||
|
it was filled by metaclass so it's always there and falls back to pk column
|
||||||
|
|
||||||
<a name="queryset.query.Query._pagination_query_required"></a>
|
<a name="queryset.query.Query._pagination_query_required"></a>
|
||||||
#### \_pagination\_query\_required
|
#### \_pagination\_query\_required
|
||||||
|
|
||||||
@ -62,11 +72,13 @@ Returns ready to run query with all joins and clauses.
|
|||||||
|
|
||||||
`(sqlalchemy.sql.selectable.Select)`: ready to run query with all joins and clauses.
|
`(sqlalchemy.sql.selectable.Select)`: ready to run query with all joins and clauses.
|
||||||
|
|
||||||
<a name="queryset.query.Query._build_pagination_subquery"></a>
|
<a name="queryset.query.Query._build_pagination_condition"></a>
|
||||||
#### \_build\_pagination\_subquery
|
#### \_build\_pagination\_condition
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _build_pagination_subquery() -> sqlalchemy.sql.select
|
| _build_pagination_condition() -> Tuple[
|
||||||
|
| sqlalchemy.sql.expression.TextClause, sqlalchemy.sql.expression.TextClause
|
||||||
|
| ]
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to apply limit and offset on main table in join only
|
In order to apply limit and offset on main table in join only
|
||||||
@ -78,9 +90,8 @@ Needed only if limit or offset are set, the flag limit_sql_raw is not set
|
|||||||
and query has select_related applied. Otherwise we can limit/offset normally
|
and query has select_related applied. Otherwise we can limit/offset normally
|
||||||
at the end of whole query.
|
at the end of whole query.
|
||||||
|
|
||||||
**Returns**:
|
The condition is added to filters to filter out desired number of main model
|
||||||
|
primary key values. Whole query is used to determine the values.
|
||||||
`(sqlalchemy.sql.select)`: constructed subquery on main table with limit, offset and order applied
|
|
||||||
|
|
||||||
<a name="queryset.query.Query._apply_expression_modifiers"></a>
|
<a name="queryset.query.Query._apply_expression_modifiers"></a>
|
||||||
#### \_apply\_expression\_modifiers
|
#### \_apply\_expression\_modifiers
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### check\_node\_not\_dict\_or\_not\_last\_node
|
#### check\_node\_not\_dict\_or\_not\_last\_node
|
||||||
|
|
||||||
```python
|
```python
|
||||||
check_node_not_dict_or_not_last_node(part: str, parts: List, current_level: Any) -> bool
|
check_node_not_dict_or_not_last_node(part: str, is_last: bool, current_level: Any) -> bool
|
||||||
```
|
```
|
||||||
|
|
||||||
Checks if given name is not present in the current level of the structure.
|
Checks if given name is not present in the current level of the structure.
|
||||||
@ -86,6 +86,27 @@ only other values are overwritten.
|
|||||||
|
|
||||||
`(Dict)`: combination of both dicts
|
`(Dict)`: combination of both dicts
|
||||||
|
|
||||||
|
<a name="queryset.utils.subtract_dict"></a>
|
||||||
|
#### subtract\_dict
|
||||||
|
|
||||||
|
```python
|
||||||
|
subtract_dict(current_dict: Any, updating_dict: Any) -> Dict
|
||||||
|
```
|
||||||
|
|
||||||
|
Update one dict with another but with regard for nested keys.
|
||||||
|
|
||||||
|
That way nested sets are unionised, dicts updated and
|
||||||
|
only other values are overwritten.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `current_dict (Dict[str, ellipsis])`: dict to update
|
||||||
|
- `updating_dict (Dict)`: dict with values to update
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Dict)`: combination of both dicts
|
||||||
|
|
||||||
<a name="queryset.utils.update_dict_from_list"></a>
|
<a name="queryset.utils.update_dict_from_list"></a>
|
||||||
#### update\_dict\_from\_list
|
#### update\_dict\_from\_list
|
||||||
|
|
||||||
@ -169,3 +190,24 @@ constructed, extracts alias based on last relation leading to target model.
|
|||||||
|
|
||||||
`(Tuple[str, Type["Model"], str])`: table prefix, target model and relation string
|
`(Tuple[str, Type["Model"], str])`: table prefix, target model and relation string
|
||||||
|
|
||||||
|
<a name="queryset.utils._process_through_field"></a>
|
||||||
|
#### \_process\_through\_field
|
||||||
|
|
||||||
|
```python
|
||||||
|
_process_through_field(related_parts: List, relation: Optional[str], related_field: "BaseField", previous_model: Type["Model"], previous_models: List[Type["Model"]]) -> Tuple[Type["Model"], Optional[str], bool]
|
||||||
|
```
|
||||||
|
|
||||||
|
Helper processing through models as they need to be treated differently.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `related_parts (List[str])`: split relation string
|
||||||
|
- `relation (str)`: relation name
|
||||||
|
- `related_field ("ForeignKeyField")`: field with relation declaration
|
||||||
|
- `previous_model (Type["Model"])`: model from which relation is coming
|
||||||
|
- `previous_models (List[Type["Model"]])`: list of already visited models in relation chain
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Tuple[Type["Model"], str, bool])`: previous_model, relation, is_through
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,7 @@ List has to have sqlalchemy names of columns (ormar aliases) not the ormar ones.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @staticmethod
|
| @staticmethod
|
||||||
| prefixed_table_name(alias: str, name: str) -> text
|
| prefixed_table_name(alias: str, table: sqlalchemy.Table) -> text
|
||||||
```
|
```
|
||||||
|
|
||||||
Creates text clause with table name with aliased name.
|
Creates text clause with table name with aliased name.
|
||||||
@ -64,7 +64,7 @@ Creates text clause with table name with aliased name.
|
|||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `alias (str)`: alias of given table
|
- `alias (str)`: alias of given table
|
||||||
- `name (str)`: table name
|
- `table (sqlalchemy.Table)`: table
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ Given model and relation name returns the alias for this relation.
|
|||||||
#### resolve\_relation\_alias\_after\_complex
|
#### resolve\_relation\_alias\_after\_complex
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| resolve_relation_alias_after_complex(source_model: Union[Type["Model"], Type["ModelRow"]], relation_str: str, relation_field: Type["ForeignKeyField"]) -> str
|
| resolve_relation_alias_after_complex(source_model: Union[Type["Model"], Type["ModelRow"]], relation_str: str, relation_field: "ForeignKeyField") -> str
|
||||||
```
|
```
|
||||||
|
|
||||||
Given source model and relation string returns the alias for this complex
|
Given source model and relation string returns the alias for this complex
|
||||||
@ -147,7 +147,7 @@ field definition.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `relation_field (Type["ForeignKeyField"])`: field with direct relation definition
|
- `relation_field ("ForeignKeyField")`: field with direct relation definition
|
||||||
- `source_model (source Model)`: model with query starts
|
- `source_model (source Model)`: model with query starts
|
||||||
- `relation_str (str)`: string with relation joins defined
|
- `relation_str (str)`: string with relation joins defined
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
## QuerysetProxy Objects
|
## QuerysetProxy Objects
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class QuerysetProxy()
|
class QuerysetProxy(Generic[T])
|
||||||
```
|
```
|
||||||
|
|
||||||
Exposes QuerySet methods on relations, but also handles creating and removing
|
Exposes QuerySet methods on relations, but also handles creating and removing
|
||||||
@ -16,7 +16,7 @@ of through Models for m2m relations.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @property
|
| @property
|
||||||
| queryset() -> "QuerySet"
|
| queryset() -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns queryset if it's set, AttributeError otherwise.
|
Returns queryset if it's set, AttributeError otherwise.
|
||||||
@ -43,7 +43,7 @@ Set's the queryset. Initialized in RelationProxy.
|
|||||||
#### \_assign\_child\_to\_parent
|
#### \_assign\_child\_to\_parent
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _assign_child_to_parent(child: Optional["Model"]) -> None
|
| _assign_child_to_parent(child: Optional["T"]) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers child in parents RelationManager.
|
Registers child in parents RelationManager.
|
||||||
@ -56,7 +56,7 @@ Registers child in parents RelationManager.
|
|||||||
#### \_register\_related
|
#### \_register\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _register_related(child: Union["Model", Sequence[Optional["Model"]]]) -> None
|
| _register_related(child: Union["T", Sequence[Optional["T"]]]) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers child/ children in parents RelationManager.
|
Registers child/ children in parents RelationManager.
|
||||||
@ -78,7 +78,7 @@ Cleans the current list of the related models.
|
|||||||
#### create\_through\_instance
|
#### create\_through\_instance
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async create_through_instance(child: "Model", **kwargs: Any) -> None
|
| async create_through_instance(child: "T", **kwargs: Any) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Crete a through model instance in the database for m2m relations.
|
Crete a through model instance in the database for m2m relations.
|
||||||
@ -92,7 +92,7 @@ Crete a through model instance in the database for m2m relations.
|
|||||||
#### update\_through\_instance
|
#### update\_through\_instance
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async update_through_instance(child: "Model", **kwargs: Any) -> None
|
| async update_through_instance(child: "T", **kwargs: Any) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates a through model instance in the database for m2m relations.
|
Updates a through model instance in the database for m2m relations.
|
||||||
@ -102,11 +102,26 @@ Updates a through model instance in the database for m2m relations.
|
|||||||
- `kwargs (Any)`: dict of additional keyword arguments for through instance
|
- `kwargs (Any)`: dict of additional keyword arguments for through instance
|
||||||
- `child (Model)`: child model instance
|
- `child (Model)`: child model instance
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.upsert_through_instance"></a>
|
||||||
|
#### upsert\_through\_instance
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async upsert_through_instance(child: "T", **kwargs: Any) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Updates a through model instance in the database for m2m relations if
|
||||||
|
it already exists, else creates one.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `kwargs (Any)`: dict of additional keyword arguments for through instance
|
||||||
|
- `child (Model)`: child model instance
|
||||||
|
|
||||||
<a name="relations.querysetproxy.QuerysetProxy.delete_through_instance"></a>
|
<a name="relations.querysetproxy.QuerysetProxy.delete_through_instance"></a>
|
||||||
#### delete\_through\_instance
|
#### delete\_through\_instance
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async delete_through_instance(child: "Model") -> None
|
| async delete_through_instance(child: "T") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Removes through model instance from the database for m2m relations.
|
Removes through model instance from the database for m2m relations.
|
||||||
@ -147,6 +162,62 @@ Actual call delegated to QuerySet.
|
|||||||
|
|
||||||
`(int)`: number of rows
|
`(int)`: number of rows
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.max"></a>
|
||||||
|
#### max
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async max(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns max value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Any)`: max value of column(s)
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.min"></a>
|
||||||
|
#### min
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async min(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns min value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Any)`: min value of column(s)
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.sum"></a>
|
||||||
|
#### sum
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async sum(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns sum value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(int)`: sum value of columns
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.avg"></a>
|
||||||
|
#### avg
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async avg(columns: Union[str, List[str]]) -> Any
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns avg value of columns for rows matching the given criteria
|
||||||
|
(applied with `filter` and `exclude` if set before).
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Union[int, float, List])`: avg value of columns
|
||||||
|
|
||||||
<a name="relations.querysetproxy.QuerysetProxy.clear"></a>
|
<a name="relations.querysetproxy.QuerysetProxy.clear"></a>
|
||||||
#### clear
|
#### clear
|
||||||
|
|
||||||
@ -175,7 +246,7 @@ or not, keep_reversed=False deletes them from database.
|
|||||||
#### first
|
#### first
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async first(**kwargs: Any) -> "Model"
|
| async first(*args: Any, **kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Gets the first row from the db ordered by primary key column ascending.
|
Gets the first row from the db ordered by primary key column ascending.
|
||||||
@ -192,11 +263,34 @@ List of related models is cleared before the call.
|
|||||||
|
|
||||||
`(_asyncio.Future)`:
|
`(_asyncio.Future)`:
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.get_or_none"></a>
|
||||||
|
#### get\_or\_none
|
||||||
|
|
||||||
|
```python
|
||||||
|
| async get_or_none(*args: Any, **kwargs: Any) -> Optional["T"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Get's the first row from the db meeting the criteria set by kwargs.
|
||||||
|
|
||||||
|
If no criteria set it will return the last row in db sorted by pk.
|
||||||
|
|
||||||
|
Passing a criteria is actually calling filter(**kwargs) method described below.
|
||||||
|
|
||||||
|
If not match is found None will be returned.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `kwargs (Any)`: fields names and proper value types
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Model)`: returned model
|
||||||
|
|
||||||
<a name="relations.querysetproxy.QuerysetProxy.get"></a>
|
<a name="relations.querysetproxy.QuerysetProxy.get"></a>
|
||||||
#### get
|
#### get
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async get(**kwargs: Any) -> "Model"
|
| async get(*args: Any, **kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Get's the first row from the db meeting the criteria set by kwargs.
|
Get's the first row from the db meeting the criteria set by kwargs.
|
||||||
@ -226,7 +320,7 @@ List of related models is cleared before the call.
|
|||||||
#### all
|
#### all
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async all(**kwargs: Any) -> Sequence[Optional["Model"]]
|
| async all(*args: Any, **kwargs: Any) -> List[Optional["T"]]
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns all rows from a database for given model for set filter options.
|
Returns all rows from a database for given model for set filter options.
|
||||||
@ -251,7 +345,7 @@ List of related models is cleared before the call.
|
|||||||
#### create
|
#### create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async create(**kwargs: Any) -> "Model"
|
| async create(**kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Creates the model instance, saves it in a database and returns the updates model
|
Creates the model instance, saves it in a database and returns the updates model
|
||||||
@ -296,7 +390,7 @@ each=True flag to affect whole table.
|
|||||||
#### get\_or\_create
|
#### get\_or\_create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async get_or_create(**kwargs: Any) -> "Model"
|
| async get_or_create(*args: Any, **kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Combination of create and get methods.
|
Combination of create and get methods.
|
||||||
@ -317,7 +411,7 @@ it creates a new one with given kwargs.
|
|||||||
#### update\_or\_create
|
#### update\_or\_create
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async update_or_create(**kwargs: Any) -> "Model"
|
| async update_or_create(**kwargs: Any) -> "T"
|
||||||
```
|
```
|
||||||
|
|
||||||
Updates the model, or in case there is no match in database creates a new one.
|
Updates the model, or in case there is no match in database creates a new one.
|
||||||
@ -336,7 +430,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### filter
|
#### filter
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| filter(**kwargs: Any) -> "QuerysetProxy"
|
| filter(*args: Any, **kwargs: Any) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Allows you to filter by any `Model` attribute/field
|
Allows you to filter by any `Model` attribute/field
|
||||||
@ -349,6 +443,8 @@ You can use special filter suffix to change the filter operands:
|
|||||||
* contains - like `album__name__contains='Mal'` (sql like)
|
* contains - like `album__name__contains='Mal'` (sql like)
|
||||||
* icontains - like `album__name__icontains='mal'` (sql like case insensitive)
|
* icontains - like `album__name__icontains='mal'` (sql like case insensitive)
|
||||||
* in - like `album__name__in=['Malibu', 'Barclay']` (sql in)
|
* in - like `album__name__in=['Malibu', 'Barclay']` (sql in)
|
||||||
|
* isnull - like `album__name__isnull=True` (sql is null)
|
||||||
|
(isnotnull `album__name__isnull=False` (sql is not null))
|
||||||
* gt - like `position__gt=3` (sql >)
|
* gt - like `position__gt=3` (sql >)
|
||||||
* gte - like `position__gte=3` (sql >=)
|
* gte - like `position__gte=3` (sql >=)
|
||||||
* lt - like `position__lt=3` (sql <)
|
* lt - like `position__lt=3` (sql <)
|
||||||
@ -372,7 +468,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### exclude
|
#### exclude
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| exclude(**kwargs: Any) -> "QuerysetProxy"
|
| exclude(*args: Any, **kwargs: Any) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Works exactly the same as filter and all modifiers (suffixes) are the same,
|
Works exactly the same as filter and all modifiers (suffixes) are the same,
|
||||||
@ -397,11 +493,40 @@ Actual call delegated to QuerySet.
|
|||||||
|
|
||||||
`(QuerysetProxy)`: filtered QuerysetProxy
|
`(QuerysetProxy)`: filtered QuerysetProxy
|
||||||
|
|
||||||
|
<a name="relations.querysetproxy.QuerysetProxy.select_all"></a>
|
||||||
|
#### select\_all
|
||||||
|
|
||||||
|
```python
|
||||||
|
| select_all(follow: bool = False) -> "QuerysetProxy[T]"
|
||||||
|
```
|
||||||
|
|
||||||
|
By default adds only directly related models.
|
||||||
|
|
||||||
|
If follow=True is set it adds also related models of related models.
|
||||||
|
|
||||||
|
To not get stuck in an infinite loop as related models also keep a relation
|
||||||
|
to parent model visited models set is kept.
|
||||||
|
|
||||||
|
That way already visited models that are nested are loaded, but the load do not
|
||||||
|
follow them inside. So Model A -> Model B -> Model C -> Model A -> Model X
|
||||||
|
will load second Model A but will never follow into Model X.
|
||||||
|
Nested relations of those kind need to be loaded manually.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `follow (bool)`: flag to trigger deep save -
|
||||||
|
by default only directly related models are saved
|
||||||
|
with follow=True also related models of related models are saved
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Model)`: reloaded Model
|
||||||
|
|
||||||
<a name="relations.querysetproxy.QuerysetProxy.select_related"></a>
|
<a name="relations.querysetproxy.QuerysetProxy.select_related"></a>
|
||||||
#### select\_related
|
#### select\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| select_related(related: Union[List, str]) -> "QuerysetProxy"
|
| select_related(related: Union[List, str]) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Allows to prefetch related models during the same query.
|
Allows to prefetch related models during the same query.
|
||||||
@ -428,7 +553,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### prefetch\_related
|
#### prefetch\_related
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| prefetch_related(related: Union[List, str]) -> "QuerysetProxy"
|
| prefetch_related(related: Union[List, str]) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Allows to prefetch related models during query - but opposite to
|
Allows to prefetch related models during query - but opposite to
|
||||||
@ -456,7 +581,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### paginate
|
#### paginate
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| paginate(page: int, page_size: int = 20) -> "QuerysetProxy"
|
| paginate(page: int, page_size: int = 20) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can paginate the result which is a combination of offset and limit clauses.
|
You can paginate the result which is a combination of offset and limit clauses.
|
||||||
@ -477,7 +602,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### limit
|
#### limit
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| limit(limit_count: int) -> "QuerysetProxy"
|
| limit(limit_count: int) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can limit the results to desired number of parent models.
|
You can limit the results to desired number of parent models.
|
||||||
@ -496,7 +621,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### offset
|
#### offset
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| offset(offset: int) -> "QuerysetProxy"
|
| offset(offset: int) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also offset the results by desired number of main models.
|
You can also offset the results by desired number of main models.
|
||||||
@ -515,7 +640,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### fields
|
#### fields
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| fields(columns: Union[List, str, Set, Dict]) -> "QuerysetProxy"
|
| fields(columns: Union[List, str, Set, Dict]) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
With `fields()` you can select subset of model columns to limit the data load.
|
With `fields()` you can select subset of model columns to limit the data load.
|
||||||
@ -568,7 +693,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### exclude\_fields
|
#### exclude\_fields
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| exclude_fields(columns: Union[List, str, Set, Dict]) -> "QuerysetProxy"
|
| exclude_fields(columns: Union[List, str, Set, Dict]) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
With `exclude_fields()` you can select subset of model columns that will
|
With `exclude_fields()` you can select subset of model columns that will
|
||||||
@ -605,7 +730,7 @@ Actual call delegated to QuerySet.
|
|||||||
#### order\_by
|
#### order\_by
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| order_by(columns: Union[List, str]) -> "QuerysetProxy"
|
| order_by(columns: Union[List, str, "OrderAction"]) -> "QuerysetProxy[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
With `order_by()` you can order the results from database based on your
|
With `order_by()` you can order the results from database based on your
|
||||||
|
|||||||
@ -50,7 +50,7 @@ Actual call is delegated to Relation instance registered under relation name.
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
| @staticmethod
|
| @staticmethod
|
||||||
| add(parent: "Model", child: "Model", field: Type["ForeignKeyField"]) -> None
|
| add(parent: "Model", child: "Model", field: "ForeignKeyField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Adds relation on both sides -> meaning on both child and parent models.
|
Adds relation on both sides -> meaning on both child and parent models.
|
||||||
@ -121,14 +121,14 @@ Returns the actual relation and not the related model(s).
|
|||||||
#### \_get\_relation\_type
|
#### \_get\_relation\_type
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _get_relation_type(field: Type["BaseField"]) -> RelationType
|
| _get_relation_type(field: "BaseField") -> RelationType
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns type of the relation declared on a field.
|
Returns type of the relation declared on a field.
|
||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `field (Type[BaseField])`: field with relation declaration
|
- `field (BaseField)`: field with relation declaration
|
||||||
|
|
||||||
**Returns**:
|
**Returns**:
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ Returns type of the relation declared on a field.
|
|||||||
#### \_add\_relation
|
#### \_add\_relation
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _add_relation(field: Type["BaseField"]) -> None
|
| _add_relation(field: "BaseField") -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Registers relation in the manager.
|
Registers relation in the manager.
|
||||||
@ -146,5 +146,5 @@ Adds Relation instance under field.name.
|
|||||||
|
|
||||||
**Arguments**:
|
**Arguments**:
|
||||||
|
|
||||||
- `field (Type[BaseField])`: field with relation declaration
|
- `field (BaseField)`: field with relation declaration
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
## RelationProxy Objects
|
## RelationProxy Objects
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class RelationProxy(list)
|
class RelationProxy(Generic[T], list)
|
||||||
```
|
```
|
||||||
|
|
||||||
Proxy of the Relation that is a list with special methods.
|
Proxy of the Relation that is a list with special methods.
|
||||||
@ -96,7 +96,7 @@ Otherwise QuerySetProxy cannot filter by parent primary key.
|
|||||||
#### \_set\_queryset
|
#### \_set\_queryset
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| _set_queryset() -> "QuerySet"
|
| _set_queryset() -> "QuerySet[T]"
|
||||||
```
|
```
|
||||||
|
|
||||||
Creates new QuerySet with relation model and pre filters it with currents
|
Creates new QuerySet with relation model and pre filters it with currents
|
||||||
@ -111,7 +111,7 @@ to the parent model only, without need for user to filter them.
|
|||||||
#### remove
|
#### remove
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async remove(item: "Model", keep_reversed: bool = True) -> None
|
| async remove(item: "T", keep_reversed: bool = True) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Removes the related from relation with parent.
|
Removes the related from relation with parent.
|
||||||
@ -131,7 +131,7 @@ will be deleted, and not only removed from relation).
|
|||||||
#### add
|
#### add
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| async add(item: "Model", **kwargs: Any) -> None
|
| async add(item: "T", **kwargs: Any) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Adds child model to relation.
|
Adds child model to relation.
|
||||||
|
|||||||
@ -18,7 +18,7 @@ Different types of relations supported by ormar:
|
|||||||
## Relation Objects
|
## Relation Objects
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class Relation()
|
class Relation(Generic[T])
|
||||||
```
|
```
|
||||||
|
|
||||||
Keeps related Models and handles adding/removing of the children.
|
Keeps related Models and handles adding/removing of the children.
|
||||||
@ -27,7 +27,7 @@ Keeps related Models and handles adding/removing of the children.
|
|||||||
#### \_\_init\_\_
|
#### \_\_init\_\_
|
||||||
|
|
||||||
```python
|
```python
|
||||||
| __init__(manager: "RelationsManager", type_: RelationType, field_name: str, to: Type["Model"], through: Type["Model"] = None) -> None
|
| __init__(manager: "RelationsManager", type_: RelationType, field_name: str, to: Type["T"], through: Type["Model"] = None) -> None
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialize the Relation and keep the related models either as instances of
|
Initialize the Relation and keep the related models either as instances of
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#### get\_relations\_sides\_and\_names
|
#### get\_relations\_sides\_and\_names
|
||||||
|
|
||||||
```python
|
```python
|
||||||
get_relations_sides_and_names(to_field: Type[ForeignKeyField], parent: "Model", child: "Model") -> Tuple["Model", "Model", str, str]
|
get_relations_sides_and_names(to_field: ForeignKeyField, parent: "Model", child: "Model") -> Tuple["Model", "Model", str, str]
|
||||||
```
|
```
|
||||||
|
|
||||||
Determines the names of child and parent relations names, as well as
|
Determines the names of child and parent relations names, as well as
|
||||||
|
|||||||
@ -128,3 +128,75 @@ that should have the signal receiver registered
|
|||||||
|
|
||||||
`(Callable)`: returns the original function untouched
|
`(Callable)`: returns the original function untouched
|
||||||
|
|
||||||
|
<a name="decorators.signals.pre_relation_add"></a>
|
||||||
|
#### pre\_relation\_add
|
||||||
|
|
||||||
|
```python
|
||||||
|
pre_relation_add(senders: Union[Type["Model"], List[Type["Model"]]]) -> Callable
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect given function to all senders for pre_relation_add signal.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `senders (Union[Type["Model"], List[Type["Model"]]])`: one or a list of "Model" classes
|
||||||
|
that should have the signal receiver registered
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Callable)`: returns the original function untouched
|
||||||
|
|
||||||
|
<a name="decorators.signals.post_relation_add"></a>
|
||||||
|
#### post\_relation\_add
|
||||||
|
|
||||||
|
```python
|
||||||
|
post_relation_add(senders: Union[Type["Model"], List[Type["Model"]]]) -> Callable
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect given function to all senders for post_relation_add signal.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `senders (Union[Type["Model"], List[Type["Model"]]])`: one or a list of "Model" classes
|
||||||
|
that should have the signal receiver registered
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Callable)`: returns the original function untouched
|
||||||
|
|
||||||
|
<a name="decorators.signals.pre_relation_remove"></a>
|
||||||
|
#### pre\_relation\_remove
|
||||||
|
|
||||||
|
```python
|
||||||
|
pre_relation_remove(senders: Union[Type["Model"], List[Type["Model"]]]) -> Callable
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect given function to all senders for pre_relation_remove signal.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `senders (Union[Type["Model"], List[Type["Model"]]])`: one or a list of "Model" classes
|
||||||
|
that should have the signal receiver registered
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Callable)`: returns the original function untouched
|
||||||
|
|
||||||
|
<a name="decorators.signals.post_relation_remove"></a>
|
||||||
|
#### post\_relation\_remove
|
||||||
|
|
||||||
|
```python
|
||||||
|
post_relation_remove(senders: Union[Type["Model"], List[Type["Model"]]]) -> Callable
|
||||||
|
```
|
||||||
|
|
||||||
|
Connect given function to all senders for post_relation_remove signal.
|
||||||
|
|
||||||
|
**Arguments**:
|
||||||
|
|
||||||
|
- `senders (Union[Type["Model"], List[Type["Model"]]])`: one or a list of "Model" classes
|
||||||
|
that should have the signal receiver registered
|
||||||
|
|
||||||
|
**Returns**:
|
||||||
|
|
||||||
|
`(Callable)`: returns the original function untouched
|
||||||
|
|
||||||
|
|||||||
@ -69,33 +69,33 @@ tracks = Track.objects.filter(album__name="Fantasies").all()
|
|||||||
|
|
||||||
You can use special filter suffix to change the filter operands:
|
You can use special filter suffix to change the filter operands:
|
||||||
|
|
||||||
* exact - exact match to value, sql `column = <VALUE>`
|
* **exact** - exact match to value, sql `column = <VALUE>`
|
||||||
* can be written as`album__name__exact='Malibu'`
|
* can be written as`album__name__exact='Malibu'`
|
||||||
* iexact - exact match sql `column = <VALUE>` (case insensitive)
|
* **iexact** - exact match sql `column = <VALUE>` (case insensitive)
|
||||||
* can be written as`album__name__iexact='malibu'`
|
* can be written as`album__name__iexact='malibu'`
|
||||||
* contains - sql `column LIKE '%<VALUE>%'`
|
* **contains** - sql `column LIKE '%<VALUE>%'`
|
||||||
* can be written as`album__name__contains='Mal'`
|
* can be written as`album__name__contains='Mal'`
|
||||||
* icontains - sql `column LIKE '%<VALUE>%'` (case insensitive)
|
* **icontains** - sql `column LIKE '%<VALUE>%'` (case insensitive)
|
||||||
* can be written as`album__name__icontains='mal'`
|
* can be written as`album__name__icontains='mal'`
|
||||||
* in - sql ` column IN (<VALUE1>, <VALUE2>, ...)`
|
* **in** - sql ` column IN (<VALUE1>, <VALUE2>, ...)`
|
||||||
* can be written as`album__name__in=['Malibu', 'Barclay']`
|
* can be written as`album__name__in=['Malibu', 'Barclay']`
|
||||||
* isnull - sql `column IS NULL` (and sql `column IS NOT NULL`)
|
* **isnull** - sql `column IS NULL` (and sql `column IS NOT NULL`)
|
||||||
* can be written as`album__name__isnull=True` (isnotnull `album__name__isnull=False`)
|
* can be written as`album__name__isnull=True` (isnotnull `album__name__isnull=False`)
|
||||||
* gt - sql `column > <VALUE>` (greater than)
|
* **gt** - sql `column > <VALUE>` (greater than)
|
||||||
* can be written as`position__gt=3`
|
* can be written as`position__gt=3`
|
||||||
* gte - sql `column >= <VALUE>` (greater or equal than)
|
* **gte** - sql `column >= <VALUE>` (greater or equal than)
|
||||||
* can be written as`position__gte=3`
|
* can be written as`position__gte=3`
|
||||||
* lt - sql `column < <VALUE>` (lower than)
|
* **lt** - sql `column < <VALUE>` (lower than)
|
||||||
* can be written as`position__lt=3`
|
* can be written as`position__lt=3`
|
||||||
* lte - sql `column <= <VALUE>` (lower equal than)
|
* **lte** - sql `column <= <VALUE>` (lower equal than)
|
||||||
* can be written as`position__lte=3`
|
* can be written as`position__lte=3`
|
||||||
* startswith - sql `column LIKE '<VALUE>%'` (exact start match)
|
* **startswith** - sql `column LIKE '<VALUE>%'` (exact start match)
|
||||||
* can be written as`album__name__startswith='Mal'`
|
* can be written as`album__name__startswith='Mal'`
|
||||||
* istartswith - sql `column LIKE '<VALUE>%'` (case insensitive)
|
* **istartswith** - sql `column LIKE '<VALUE>%'` (case insensitive)
|
||||||
* can be written as`album__name__istartswith='mal'`
|
* can be written as`album__name__istartswith='mal'`
|
||||||
* endswith - sql `column LIKE '%<VALUE>'` (exact end match)
|
* **endswith** - sql `column LIKE '%<VALUE>'` (exact end match)
|
||||||
* can be written as`album__name__endswith='ibu'`
|
* can be written as`album__name__endswith='ibu'`
|
||||||
* iendswith - sql `column LIKE '%<VALUE>'` (case insensitive)
|
* **iendswith** - sql `column LIKE '%<VALUE>'` (case insensitive)
|
||||||
* can be written as`album__name__iendswith='IBU'`
|
* can be written as`album__name__iendswith='IBU'`
|
||||||
|
|
||||||
Some samples:
|
Some samples:
|
||||||
@ -116,39 +116,39 @@ Product.objects.filter(
|
|||||||
|
|
||||||
### Python style filters
|
### Python style filters
|
||||||
|
|
||||||
* exact - exact match to value, sql `column = <VALUE>`
|
* **exact** - exact match to value, sql `column = <VALUE>`
|
||||||
* can be written as `Track.album.name == 'Malibu`
|
* can be written as `Track.album.name == 'Malibu`
|
||||||
* iexact - exact match sql `column = <VALUE>` (case insensitive)
|
* **iexact** - exact match sql `column = <VALUE>` (case insensitive)
|
||||||
* can be written as `Track.album.name.iexact('malibu')`
|
* can be written as `Track.album.name.iexact('malibu')`
|
||||||
* contains - sql `column LIKE '%<VALUE>%'`
|
* **contains** - sql `column LIKE '%<VALUE>%'`
|
||||||
* can be written as `Track.album.name % 'Mal')`
|
* can be written as `Track.album.name % 'Mal')`
|
||||||
* can be written as `Track.album.name.contains('Mal')`
|
* can be written as `Track.album.name.contains('Mal')`
|
||||||
* icontains - sql `column LIKE '%<VALUE>%'` (case insensitive)
|
* **icontains** - sql `column LIKE '%<VALUE>%'` (case insensitive)
|
||||||
* can be written as `Track.album.name.icontains('mal')`
|
* can be written as `Track.album.name.icontains('mal')`
|
||||||
* in - sql ` column IN (<VALUE1>, <VALUE2>, ...)`
|
* **in** - sql ` column IN (<VALUE1>, <VALUE2>, ...)`
|
||||||
* can be written as `Track.album.name << ['Malibu', 'Barclay']`
|
* can be written as `Track.album.name << ['Malibu', 'Barclay']`
|
||||||
* can be written as `Track.album.name.in_(['Malibu', 'Barclay'])`
|
* can be written as `Track.album.name.in_(['Malibu', 'Barclay'])`
|
||||||
* isnull - sql `column IS NULL` (and sql `column IS NOT NULL`)
|
* **isnull** - sql `column IS NULL` (and sql `column IS NOT NULL`)
|
||||||
* can be written as `Track.album.name >> None`
|
* can be written as `Track.album.name >> None`
|
||||||
* can be written as `Track.album.name.is_null(True)`
|
* can be written as `Track.album.name.isnull(True)`
|
||||||
* not null can be written as `Track.album.name.is_null(False)`
|
* not null can be written as `Track.album.name.isnull(False)`
|
||||||
* not null can be written as `~(Track.album.name >> None)`
|
* not null can be written as `~(Track.album.name >> None)`
|
||||||
* not null can be written as `~(Track.album.name.is_null(True))`
|
* not null can be written as `~(Track.album.name.isnull(True))`
|
||||||
* gt - sql `column > <VALUE>` (greater than)
|
* **gt** - sql `column > <VALUE>` (greater than)
|
||||||
* can be written as `Track.album.name > 3`
|
* can be written as `Track.album.name > 3`
|
||||||
* gte - sql `column >= <VALUE>` (greater or equal than)
|
* **gte** - sql `column >= <VALUE>` (greater or equal than)
|
||||||
* can be written as `Track.album.name >= 3`
|
* can be written as `Track.album.name >= 3`
|
||||||
* lt - sql `column < <VALUE>` (lower than)
|
* **lt** - sql `column < <VALUE>` (lower than)
|
||||||
* can be written as `Track.album.name < 3`
|
* can be written as `Track.album.name < 3`
|
||||||
* lte - sql `column <= <VALUE>` (lower equal than)
|
* **lte** - sql `column <= <VALUE>` (lower equal than)
|
||||||
* can be written as `Track.album.name <= 3`
|
* can be written as `Track.album.name <= 3`
|
||||||
* startswith - sql `column LIKE '<VALUE>%'` (exact start match)
|
* **startswith** - sql `column LIKE '<VALUE>%'` (exact start match)
|
||||||
* can be written as `Track.album.name.startswith('Mal')`
|
* can be written as `Track.album.name.startswith('Mal')`
|
||||||
* istartswith - sql `column LIKE '<VALUE>%'` (case insensitive)
|
* **istartswith** - sql `column LIKE '<VALUE>%'` (case insensitive)
|
||||||
* can be written as `Track.album.name.istartswith('mal')`
|
* can be written as `Track.album.name.istartswith('mal')`
|
||||||
* endswith - sql `column LIKE '%<VALUE>'` (exact end match)
|
* **endswith** - sql `column LIKE '%<VALUE>'` (exact end match)
|
||||||
* can be written as `Track.album.name.endswith('ibu')`
|
* can be written as `Track.album.name.endswith('ibu')`
|
||||||
* iendswith - sql `column LIKE '%<VALUE>'` (case insensitive)
|
* **iendswith** - sql `column LIKE '%<VALUE>'` (case insensitive)
|
||||||
* can be written as `Track.album.name.iendswith('IBU')`
|
* can be written as `Track.album.name.iendswith('IBU')`
|
||||||
|
|
||||||
Some samples:
|
Some samples:
|
||||||
@ -291,7 +291,7 @@ Let's select books of Tolkien **OR** books written after 1970
|
|||||||
sql:
|
sql:
|
||||||
`WHERE ( authors.name = 'J.R.R. Tolkien' OR books.year > 1970 )`
|
`WHERE ( authors.name = 'J.R.R. Tolkien' OR books.year > 1970 )`
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -301,7 +301,7 @@ books = (
|
|||||||
assert len(books) == 5
|
assert len(books) == 5
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -316,7 +316,7 @@ Now let's select books written after 1960 or before 1940 which were written by T
|
|||||||
sql:
|
sql:
|
||||||
`WHERE ( books.year > 1960 OR books.year < 1940 ) AND authors.name = 'J.R.R. Tolkien'`
|
`WHERE ( books.year > 1960 OR books.year < 1940 ) AND authors.name = 'J.R.R. Tolkien'`
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
# OPTION 1 - split and into separate call
|
# OPTION 1 - split and into separate call
|
||||||
books = (
|
books = (
|
||||||
@ -344,7 +344,7 @@ assert books[0].title == "The Hobbit"
|
|||||||
assert books[1].title == "The Silmarillion"
|
assert books[1].title == "The Silmarillion"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -375,7 +375,7 @@ Books of Sapkowski from before 2000 or books of Tolkien written after 1960
|
|||||||
sql:
|
sql:
|
||||||
`WHERE ( ( books.year > 1960 AND authors.name = 'J.R.R. Tolkien' ) OR ( books.year < 2000 AND authors.name = 'Andrzej Sapkowski' ) ) `
|
`WHERE ( ( books.year > 1960 AND authors.name = 'J.R.R. Tolkien' ) OR ( books.year < 2000 AND authors.name = 'Andrzej Sapkowski' ) ) `
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -390,7 +390,7 @@ books = (
|
|||||||
assert len(books) == 2
|
assert len(books) == 2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -411,7 +411,7 @@ sql:
|
|||||||
( books.year < 2000 AND os0cec_authors.name = 'Andrzej Sapkowski' ) OR
|
( books.year < 2000 AND os0cec_authors.name = 'Andrzej Sapkowski' ) OR
|
||||||
books.title LIKE '%hobbit%' )`
|
books.title LIKE '%hobbit%' )`
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -426,7 +426,7 @@ books = (
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -451,7 +451,7 @@ AND authors.name = 'J.R.R. Tolkien' ) OR
|
|||||||
|
|
||||||
You can construct a query as follows:
|
You can construct a query as follows:
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
@ -472,16 +472,21 @@ assert books[1].title == "The Silmarillion"
|
|||||||
assert books[2].title == "The Witcher"
|
assert books[2].title == "The Witcher"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Python style
|
||||||
```python
|
```python
|
||||||
books = (
|
books = (
|
||||||
await Book.objects.select_related("author")
|
await Book.objects.select_related("author")
|
||||||
.filter(
|
.filter(
|
||||||
ormar.or_(
|
(
|
||||||
ormar.and_(
|
(
|
||||||
ormar.or_(year__gt=1960, year__lt=1940),
|
(Book.year > 1960) |
|
||||||
author__name="J.R.R. Tolkien",
|
(Book.year < 1940)
|
||||||
),
|
) &
|
||||||
ormar.and_(year__lt=2000, author__name="Andrzej Sapkowski"),
|
(Book.author.name == "J.R.R. Tolkien")
|
||||||
|
) |
|
||||||
|
(
|
||||||
|
(Book.year < 2000) &
|
||||||
|
(Book.author.name == "Andrzej Sapkowski")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.all()
|
.all()
|
||||||
@ -512,7 +517,7 @@ assert books[0].title == "The Witcher"
|
|||||||
|
|
||||||
Same applies to python style chaining and nesting.
|
Same applies to python style chaining and nesting.
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
|
|
||||||
Note that with django style you cannot provide the same keyword argument several times so queries like `filter(ormar.or_(name='Jack', name='John'))` are not allowed. If you want to check the same
|
Note that with django style you cannot provide the same keyword argument several times so queries like `filter(ormar.or_(name='Jack', name='John'))` are not allowed. If you want to check the same
|
||||||
column for several values simply use `in` operator: `filter(name__in=['Jack','John'])`.
|
column for several values simply use `in` operator: `filter(name__in=['Jack','John'])`.
|
||||||
@ -559,7 +564,7 @@ books = (
|
|||||||
assert len(books) == 5
|
assert len(books) == 5
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
|
|
||||||
Note that with python style you can perfectly use the same fields as many times as you want.
|
Note that with python style you can perfectly use the same fields as many times as you want.
|
||||||
|
|
||||||
@ -721,7 +726,7 @@ Given sample Models like following:
|
|||||||
|
|
||||||
To order by main model field just provide a field name
|
To order by main model field just provide a field name
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
toys = await Toy.objects.select_related("owner").order_by("name").all()
|
toys = await Toy.objects.select_related("owner").order_by("name").all()
|
||||||
assert [x.name.replace("Toy ", "") for x in toys] == [
|
assert [x.name.replace("Toy ", "") for x in toys] == [
|
||||||
@ -731,7 +736,7 @@ assert toys[0].owner == zeus
|
|||||||
assert toys[1].owner == aphrodite
|
assert toys[1].owner == aphrodite
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
toys = await Toy.objects.select_related("owner").order_by(Toy.name.asc()).all()
|
toys = await Toy.objects.select_related("owner").order_by(Toy.name.asc()).all()
|
||||||
assert [x.name.replace("Toy ", "") for x in toys] == [
|
assert [x.name.replace("Toy ", "") for x in toys] == [
|
||||||
@ -747,7 +752,7 @@ To sort on nested models separate field names with dunder '__'.
|
|||||||
You can sort this way across all relation types -> `ForeignKey`, reverse virtual FK
|
You can sort this way across all relation types -> `ForeignKey`, reverse virtual FK
|
||||||
and `ManyToMany` fields.
|
and `ManyToMany` fields.
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
toys = await Toy.objects.select_related("owner").order_by("owner__name").all()
|
toys = await Toy.objects.select_related("owner").order_by("owner__name").all()
|
||||||
assert toys[0].owner.name == toys[1].owner.name == "Aphrodite"
|
assert toys[0].owner.name == toys[1].owner.name == "Aphrodite"
|
||||||
@ -755,7 +760,7 @@ assert toys[2].owner.name == toys[3].owner.name == "Hermes"
|
|||||||
assert toys[4].owner.name == toys[5].owner.name == "Zeus"
|
assert toys[4].owner.name == toys[5].owner.name == "Zeus"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
toys = await Toy.objects.select_related("owner").order_by(Toy.owner.name.asc()).all()
|
toys = await Toy.objects.select_related("owner").order_by(Toy.owner.name.asc()).all()
|
||||||
assert toys[0].owner.name == toys[1].owner.name == "Aphrodite"
|
assert toys[0].owner.name == toys[1].owner.name == "Aphrodite"
|
||||||
@ -765,7 +770,7 @@ assert toys[4].owner.name == toys[5].owner.name == "Zeus"
|
|||||||
|
|
||||||
To sort in descending order provide a hyphen in front of the field name
|
To sort in descending order provide a hyphen in front of the field name
|
||||||
|
|
||||||
### Django style
|
#### Django style
|
||||||
```python
|
```python
|
||||||
owner = (
|
owner = (
|
||||||
await Owner.objects.select_related("toys")
|
await Owner.objects.select_related("toys")
|
||||||
@ -777,7 +782,7 @@ assert owner.toys[0].name == "Toy 4"
|
|||||||
assert owner.toys[1].name == "Toy 1"
|
assert owner.toys[1].name == "Toy 1"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python style
|
#### Python style
|
||||||
```python
|
```python
|
||||||
owner = (
|
owner = (
|
||||||
await Owner.objects.select_related("toys")
|
await Owner.objects.select_related("toys")
|
||||||
|
|||||||
@ -25,10 +25,10 @@
|
|||||||
* isnull - sql `column IS NULL` (and sql `column IS NOT NULL`)
|
* isnull - sql `column IS NULL` (and sql `column IS NOT NULL`)
|
||||||
* OLD: `album__name__isnull=True` (isnotnull `album__name__isnull=False`)
|
* OLD: `album__name__isnull=True` (isnotnull `album__name__isnull=False`)
|
||||||
* NEW: can be also written as `Track.album.name >> None`
|
* NEW: can be also written as `Track.album.name >> None`
|
||||||
* NEW: can be also written as `Track.album.name.is_null(True)`
|
* NEW: can be also written as `Track.album.name.isnull(True)`
|
||||||
* NEW: not null can be also written as `Track.album.name.is_null(False)`
|
* NEW: not null can be also written as `Track.album.name.isnull(False)`
|
||||||
* NEW: not null can be also written as `~(Track.album.name >> None)`
|
* NEW: not null can be also written as `~(Track.album.name >> None)`
|
||||||
* NEW: not null can be also written as `~(Track.album.name.is_null(True))`
|
* NEW: not null can be also written as `~(Track.album.name.isnull(True))`
|
||||||
* gt - sql `column > <VALUE>` (greater than)
|
* gt - sql `column > <VALUE>` (greater than)
|
||||||
* OLD: `position__gt=3`
|
* OLD: `position__gt=3`
|
||||||
* NEW: can be also written as `Track.album.name > 3`
|
* NEW: can be also written as `Track.album.name > 3`
|
||||||
|
|||||||
@ -77,6 +77,7 @@ nav:
|
|||||||
- Order Query: api/query-set/order-query.md
|
- Order Query: api/query-set/order-query.md
|
||||||
- Limit Query: api/query-set/limit-query.md
|
- Limit Query: api/query-set/limit-query.md
|
||||||
- Offset Query: api/query-set/offset-query.md
|
- Offset Query: api/query-set/offset-query.md
|
||||||
|
- Field Accessor: api/query-set/field-accessor.md
|
||||||
- api/query-set/utils.md
|
- api/query-set/utils.md
|
||||||
- Relations:
|
- Relations:
|
||||||
- Relation Manager: api/relations/relation-manager.md
|
- Relation Manager: api/relations/relation-manager.md
|
||||||
|
|||||||
@ -9,6 +9,11 @@ if TYPE_CHECKING: # pragma: no cover
|
|||||||
|
|
||||||
|
|
||||||
class FieldAccessor:
|
class FieldAccessor:
|
||||||
|
"""
|
||||||
|
Helper to access ormar fields directly from Model class also for nested
|
||||||
|
models attributes.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
source_model: Type["Model"],
|
source_model: Type["Model"],
|
||||||
@ -22,10 +27,24 @@ class FieldAccessor:
|
|||||||
self._access_chain = access_chain
|
self._access_chain = access_chain
|
||||||
|
|
||||||
def __bool__(self) -> bool:
|
def __bool__(self) -> bool:
|
||||||
# hack to avoid pydantic name check from parent model
|
"""
|
||||||
|
Hack to avoid pydantic name check from parent model, returns false
|
||||||
|
|
||||||
|
:return: False
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __getattr__(self, item: str) -> Any:
|
def __getattr__(self, item: str) -> Any:
|
||||||
|
"""
|
||||||
|
Accessor return new accessor for each field and nested models.
|
||||||
|
Thanks to that operator overload is possible to use in filter.
|
||||||
|
|
||||||
|
:param item: attribute name
|
||||||
|
:type item: str
|
||||||
|
:return: FieldAccessor for field or nested model
|
||||||
|
:rtype: ormar.queryset.field_accessor.FieldAccessor
|
||||||
|
"""
|
||||||
if self._field and item == self._field.name:
|
if self._field and item == self._field.name:
|
||||||
return self._field
|
return self._field
|
||||||
|
|
||||||
@ -57,60 +76,208 @@ class FieldAccessor:
|
|||||||
return FilterGroup(**filter_kwg)
|
return FilterGroup(**filter_kwg)
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> FilterGroup: # type: ignore
|
def __eq__(self, other: Any) -> FilterGroup: # type: ignore
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column = <VALUE>`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="__eq__", other=other)
|
return self._select_operator(op="__eq__", other=other)
|
||||||
|
|
||||||
def __ge__(self, other: Any) -> FilterGroup:
|
def __ge__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column >= <VALUE>`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="__ge__", other=other)
|
return self._select_operator(op="__ge__", other=other)
|
||||||
|
|
||||||
def __gt__(self, other: Any) -> FilterGroup:
|
def __gt__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column > <VALUE>`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="__gt__", other=other)
|
return self._select_operator(op="__gt__", other=other)
|
||||||
|
|
||||||
def __le__(self, other: Any) -> FilterGroup:
|
def __le__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column <= <VALUE>`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="__le__", other=other)
|
return self._select_operator(op="__le__", other=other)
|
||||||
|
|
||||||
def __lt__(self, other: Any) -> FilterGroup:
|
def __lt__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column < <VALUE>`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="__lt__", other=other)
|
return self._select_operator(op="__lt__", other=other)
|
||||||
|
|
||||||
def __mod__(self, other: Any) -> FilterGroup:
|
def __mod__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column LIKE '%<VALUE>%'`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="__mod__", other=other)
|
return self._select_operator(op="__mod__", other=other)
|
||||||
|
|
||||||
def __lshift__(self, other: Any) -> FilterGroup:
|
def __lshift__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column IN (<VALUE1>, <VALUE2>,...)`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="in", other=other)
|
return self._select_operator(op="in", other=other)
|
||||||
|
|
||||||
def __rshift__(self, other: Any) -> FilterGroup:
|
def __rshift__(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
overloaded to work as sql `column IS NULL`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="isnull", other=True)
|
return self._select_operator(op="isnull", other=True)
|
||||||
|
|
||||||
def in_(self, other: Any) -> FilterGroup:
|
def in_(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column IN (<VALUE1>, <VALUE2>,...)`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="in", other=other)
|
return self._select_operator(op="in", other=other)
|
||||||
|
|
||||||
def iexact(self, other: Any) -> FilterGroup:
|
def iexact(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column = <VALUE>` case-insensitive
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="iexact", other=other)
|
return self._select_operator(op="iexact", other=other)
|
||||||
|
|
||||||
def contains(self, other: Any) -> FilterGroup:
|
def contains(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column LIKE '%<VALUE>%'`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="contains", other=other)
|
return self._select_operator(op="contains", other=other)
|
||||||
|
|
||||||
def icontains(self, other: Any) -> FilterGroup:
|
def icontains(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column LIKE '%<VALUE>%'` case-insensitive
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="icontains", other=other)
|
return self._select_operator(op="icontains", other=other)
|
||||||
|
|
||||||
def startswith(self, other: Any) -> FilterGroup:
|
def startswith(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column LIKE '<VALUE>%'`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="startswith", other=other)
|
return self._select_operator(op="startswith", other=other)
|
||||||
|
|
||||||
def istartswith(self, other: Any) -> FilterGroup:
|
def istartswith(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column LIKE '%<VALUE>'` case-insensitive
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="istartswith", other=other)
|
return self._select_operator(op="istartswith", other=other)
|
||||||
|
|
||||||
def endswith(self, other: Any) -> FilterGroup:
|
def endswith(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column LIKE '%<VALUE>'`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="endswith", other=other)
|
return self._select_operator(op="endswith", other=other)
|
||||||
|
|
||||||
def iendswith(self, other: Any) -> FilterGroup:
|
def iendswith(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column LIKE '%<VALUE>'` case-insensitive
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="iendswith", other=other)
|
return self._select_operator(op="iendswith", other=other)
|
||||||
|
|
||||||
def isnull(self, other: Any) -> FilterGroup:
|
def isnull(self, other: Any) -> FilterGroup:
|
||||||
|
"""
|
||||||
|
works as sql `column IS NULL` or `IS NOT NULL`
|
||||||
|
|
||||||
|
:param other: value to check agains operator
|
||||||
|
:type other: str
|
||||||
|
:return: FilterGroup for operator
|
||||||
|
:rtype: ormar.queryset.clause.FilterGroup
|
||||||
|
"""
|
||||||
return self._select_operator(op="isnull", other=other)
|
return self._select_operator(op="isnull", other=other)
|
||||||
|
|
||||||
def asc(self) -> OrderAction:
|
def asc(self) -> OrderAction:
|
||||||
|
"""
|
||||||
|
works as sql `column asc`
|
||||||
|
|
||||||
|
:return: OrderGroup for operator
|
||||||
|
:rtype: ormar.queryset.actions.OrderGroup
|
||||||
|
"""
|
||||||
return OrderAction(order_str=self._access_chain, model_cls=self._source_model)
|
return OrderAction(order_str=self._access_chain, model_cls=self._source_model)
|
||||||
|
|
||||||
def desc(self) -> OrderAction:
|
def desc(self) -> OrderAction:
|
||||||
|
"""
|
||||||
|
works as sql `column desc`
|
||||||
|
|
||||||
|
:return: OrderGroup for operator
|
||||||
|
:rtype: ormar.queryset.actions.OrderGroup
|
||||||
|
"""
|
||||||
return OrderAction(
|
return OrderAction(
|
||||||
order_str="-" + self._access_chain, model_cls=self._source_model
|
order_str="-" + self._access_chain, model_cls=self._source_model
|
||||||
)
|
)
|
||||||
|
|||||||
@ -122,6 +122,9 @@ renderer:
|
|||||||
- title: Offset Query
|
- title: Offset Query
|
||||||
contents:
|
contents:
|
||||||
- queryset.offset_query.*
|
- queryset.offset_query.*
|
||||||
|
- title: Field accessor
|
||||||
|
contents:
|
||||||
|
- queryset.field_accessor.*
|
||||||
- title: Utils
|
- title: Utils
|
||||||
contents:
|
contents:
|
||||||
- queryset.utils.*
|
- queryset.utils.*
|
||||||
|
|||||||
Reference in New Issue
Block a user