4.7 KiB
Model methods
!!!tip
Main interaction with the databases is exposed through a QuerySet object exposed on
each model as Model.objects similar to the django orm.
To read more about **quering, joining tables, excluding fields etc. visit [queries][queries] section.**
Each model instance have a set of methods to save, update or load itself.
Available methods are described below.
load
By default when you query a table without prefetching related models, the ormar will still construct
your related models, but populate them only with the pk value. You can load the related model by calling load() method.
load() can also be used to refresh the model from the database (if it was changed by some other process).
track = await Track.objects.get(name='The Bird')
track.album.pk # will return malibu album pk (1)
track.album.name # will return None
# you need to actually load the data first
await track.album.load()
track.album.name # will return 'Malibu'
save
save() -> self
You can create new models by using QuerySet.create() method or by initializing your model as a normal pydantic model
and later calling save() method.
save() can also be used to persist changes that you made to the model, but only if the primary key is not set or the model does not exist in database.
The save() method does not check if the model exists in db, so if it does you will get a integrity error from your selected db backend if trying to save model with already existing primary key.
track = Track(name='The Bird')
await track.save() # will persist the model in database
track = await Track.objects.get(name='The Bird')
await track.save() # will raise integrity error as pk is populated
update
update(**kwargs) -> self
You can update models by using QuerySet.update() method or by updating your model attributes (fields) and calling update() method.
If you try to update a model without a primary key set a ModelPersistenceError exception will be thrown.
To persist a newly created model use save() or upsert(**kwargs) methods.
track = await Track.objects.get(name='The Bird')
await track.update(name='The Bird Strikes Again')
upsert
upsert(**kwargs) -> self
It's an proxy to either save() or update(**kwargs) methods described above.
If the primary key is set -> the update method will be called.
If the pk is not set the save() method will be called.
track = Track(name='The Bird')
await track.upsert() # will call save as the pk is empty
track = await Track.objects.get(name='The Bird')
await track.upsert(name='The Bird Strikes Again') # will call update as pk is already populated
delete
You can delete models by using QuerySet.delete() method or by using your model and calling delete() method.
track = await Track.objects.get(name='The Bird')
await track.delete() # will delete the model from database
!!!tip
Note that that track object stays the same, only record in the database is removed.
save_related
save_related(follow: bool = False) -> None
Method goes through all relations of the Model on which the method is called,
and calls upsert() method on each model that is not saved.
To understand when a model is saved check save status section above.
By default the save_related method saved only models that are directly related (one step away) to the model on which the method is called.
But you can specify the follow=True parameter to traverse through nested models and save all of them in the relation tree.
!!!warning
To avoid circular updates with follow=True set, save_related keeps a set of already visited Models,
and won't perform nested save_related on Models that were already visited.
So if you have a diamond or circular relations types you need to perform the updates in a manual way.
```python
# in example like this the second Street (coming from City) won't be save_related, so ZipCode won't be updated
Street -> District -> City -> Street -> ZipCode
```