Skip to content

Commit 763759f

Browse files
author
Callum Dickinson
committed
Add support for updating records
This adds support for updating records in place, using new `update` methods added to the record and record manager base classes. The `update` method has the same smart evaluation of field names based on record classes that the `create` method has. This allows ID or object field names to be used for model refs, and field aliases.
1 parent 8390d8d commit 763759f

File tree

6 files changed

+123
-5
lines changed

6 files changed

+123
-5
lines changed

changelog.d/8.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for updating records

docs/managers/account-move.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ Values:
265265
* ``reversed`` - Reversed
266266
* ``invoicing_legacy`` - Invoicing App Legacy
267267

268-
### state
268+
### `state`
269269

270270
```python
271271
state: Literal["draft", "posted", "cancel"]

docs/managers/index.md

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -770,14 +770,55 @@ pass the returned IDs to the [``list``](#list) method.
770770
|-------------|--------------------------------------|
771771
| `list[int]` | The IDs of the newly created records |
772772

773+
### `update`
774+
775+
```python
776+
def update(record: int | Record, **fields: Any) -> None
777+
```
778+
779+
Update one or more fields on this record in place.
780+
781+
```python
782+
>>> from openstack_odooclient import Client as OdooClient
783+
>>> odoo_client = OdooClient(
784+
... hostname="localhost",
785+
... port=8069,
786+
... protocol="jsonrpc",
787+
... database="odoodb",
788+
... user="test-user",
789+
... password="<password>",
790+
... )
791+
>>> odoo_client.users.get(1234)
792+
User(record={'id': 1234, 'name': 'Old Name', ...}, fields=None)
793+
>>> odoo_client.users.update(1234, name="New Name")
794+
>>> odoo_client.users.get(1234)
795+
User(record={'id': 1234, 'name': 'New Name', ...}, fields=None)
796+
```
797+
798+
Field names are passed as keyword arguments.
799+
This method has the same flexibility with regards to what
800+
field names are used as when [creating records](#create);
801+
for example, when updating a model ref, either its ID
802+
(e.g. ``user_id``) or object (e.g. ``user``) field names
803+
can be used.
804+
805+
*Added in version 0.2.0.*
806+
807+
#### Parameters
808+
809+
| Name | Type | Description | Default |
810+
|------------|----------------|-----------------------------------------|------------|
811+
| `record` | `int | Record` | The record to update (object or ID) | (required) |
812+
| `**fields` | `Any` | Record field values (keyword arguments) | (required) |
813+
773814
### `unlink`/`delete`
774815

775816
```python
776-
unlink(*records: Record | int | Iterable[Record | int]) -> None
817+
unlink(*records: int | Record | Iterable[int | Record]) -> None
777818
```
778819

779820
```python
780-
delete(*records: Record | int | Iterable[Record | int]) -> None
821+
delete(*records: int | Record | Iterable[int | Record]) -> None
781822
```
782823

783824
Delete one or more records from Odoo.
@@ -1357,6 +1398,44 @@ User(record={'id': 1234, ...}, fields=None)
13571398
|------------------|-------------------|
13581399
| `dict[str, Any]` | Record dictionary |
13591400

1401+
#### `update`
1402+
1403+
```python
1404+
def update(**fields: Any) -> None
1405+
```
1406+
1407+
Update one or more fields on this record in place.
1408+
1409+
```python
1410+
>>> user
1411+
User(record={'id': 1234, 'name': 'Old Name', ...}, fields=None)
1412+
>>> user.update(name="New Name")
1413+
>>> user.refresh()
1414+
User(record={'id': 1234, 'name': 'New Name', ...}, fields=None)
1415+
```
1416+
1417+
Field names are passed as keyword arguments.
1418+
This method has the same flexibility with regards to what
1419+
field names are used as when [creating records](#create);
1420+
for example, when updating a model ref, either its ID
1421+
(e.g. ``user_id``) or object (e.g. ``user``) field names
1422+
can be used.
1423+
1424+
!!! note
1425+
1426+
This record object is not updated in place by this method.
1427+
1428+
If you need an updated version of the record object,
1429+
use the [`refresh`](#refresh) method to fetch the latest version.
1430+
1431+
*Added in version 0.2.0.*
1432+
1433+
##### Parameters
1434+
1435+
| Name | Type | Description | Default |
1436+
|------------|-------|-----------------------------------------|------------|
1437+
| `**fields` | `Any` | Record field values (keyword arguments) | (required) |
1438+
13601439
#### `refresh`
13611440

13621441
```python
@@ -1395,9 +1474,10 @@ Delete this record from Odoo.
13951474

13961475
```python
13971476
>>> user
1398-
User(record={'id': 1234, 'name': 'Old Name', ...}, fields=None)
1477+
User(record={'id': 1234, ...}, fields=None)
13991478
>>> user.unlink()
14001479
>>> user.refresh()
1480+
Traceback (most recent call last):
14011481
...
14021482
openstack_odooclient.exceptions.RecordNotFoundError: User record not found with ID: 1234
14031483
```

openstack_odooclient/base/record.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,23 @@ def as_dict(self, raw: bool = False) -> dict[str, Any]:
266266
}
267267
)
268268

269+
def update(self, **fields: Any) -> None:
270+
"""Update one or more fields on this record in place.
271+
272+
Field names are passed as keyword arguments.
273+
This method has the same flexibility with regards to what
274+
field names are used as when creating records; for example,
275+
when updating a model ref, either its ID (e.g. ``user_id``)
276+
or object (e.g. ``user``) field names can be used.
277+
278+
Note that this record object is not updated in place by
279+
this method. If you need an updated version of the record
280+
object, use the `refresh` method to fetch the latest version.
281+
282+
*Added in version 0.2.0.*
283+
"""
284+
self._manager.update(self.id, **fields)
285+
269286
def refresh(self) -> Self:
270287
"""Fetch the latest version of this record from Odoo.
271288

openstack_odooclient/base/record_manager.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ def _encode_filter_field(self, field: str) -> tuple[Any, str]:
629629
type_hint = self._record_type_hints[local_field]
630630
return (type_hint, remote_field)
631631

632-
def create(self, **fields) -> int:
632+
def create(self, **fields: Any) -> int:
633633
"""Create a new record, using the specified keyword arguments
634634
as input fields.
635635
@@ -808,6 +808,25 @@ def _encode_create_field(
808808
self._encode_value(type_hint=type_hint, value=value),
809809
)
810810

811+
def update(self, record: int | Record, **fields: Any) -> None:
812+
"""Update one or more fields on the given record in place.
813+
814+
Field names are passed as keyword arguments.
815+
This method has the same flexibility with regards to what
816+
field names are used as when creating records; for example,
817+
when updating a model ref, either its ID (e.g. ``user_id``)
818+
or object (e.g. ``user``) field names can be used.
819+
820+
*Added in version 0.2.0.*
821+
822+
:param record: The record to update (object or ID)
823+
:type record: int | Record
824+
"""
825+
self._env.update(
826+
record.id if isinstance(record, RecordBase) else record,
827+
self._encode_create_fields(fields),
828+
)
829+
811830
def unlink(
812831
self,
813832
*records: int | Record | Iterable[int | Record],

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ packages = ["openstack_odooclient"]
6363
[tool.poe.tasks]
6464
lint = "ruff check"
6565
format = "ruff format"
66+
type-check = "mypy openstack_odooclient"
6667

6768
[tool.ruff]
6869
fix = true

0 commit comments

Comments
 (0)