156 lines
4.7 KiB
Markdown
156 lines
4.7 KiB
Markdown
# Queries
|
|
|
|
## QuerySet
|
|
|
|
Each Model is auto registered with a QuerySet that represents the underlaying query and it's options.
|
|
|
|
Given the Models like this
|
|
|
|
```Python
|
|
--8<-- "../docs_src/relations/docs001.py"
|
|
```
|
|
|
|
we can demonstrate available methods to fetch and save the data into the database.
|
|
|
|
### create(**kwargs)
|
|
|
|
Creates the model instance, saves it in a database and returns the updates model (with pk populated).
|
|
The allowed kwargs are `Model` fields names and proper value types.
|
|
|
|
```python
|
|
malibu = await Album.objects.create(name="Malibu")
|
|
await Track.objects.create(album=malibu, title="The Bird", position=1)
|
|
```
|
|
|
|
The alternative is a split creation and persistence of the `Model`.
|
|
```python
|
|
malibu = Album(name="Malibu")
|
|
await malibu.save()
|
|
```
|
|
|
|
### 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.
|
|
|
|
```python
|
|
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'
|
|
```
|
|
|
|
### get(**kwargs)
|
|
|
|
Get's the first row from the db meeting the criteria set by kwargs.
|
|
|
|
If no criteria set it will return the first row in db.
|
|
|
|
Passing a criteria is actually calling filter(**kwargs) method described below.
|
|
|
|
```python
|
|
track = await Track.objects.get(name='The Bird')
|
|
track2 = track = await Track.objects.get()
|
|
track == track2 # True since it's the only row in db
|
|
```
|
|
|
|
### all()
|
|
|
|
Returns all rows from a database for given model
|
|
|
|
```python
|
|
tracks = await Track.objects.select_related("album").all()
|
|
# will return a list of all Tracks
|
|
```
|
|
|
|
### filter(**kwargs)
|
|
|
|
Allows you to filter by any `Model` attribute/field
|
|
as well as to fetch instances, with a filter across an FK relationship.
|
|
|
|
```python
|
|
track = Track.objects.filter(name="The Bird").get()
|
|
# will return a track with name equal to 'The Bird'
|
|
|
|
tracks = Track.objects.filter(album__name="Fantasies").all()
|
|
# will return all tracks where the related album name = 'Fantasies'
|
|
```
|
|
|
|
You can use special filter suffix to change the filter operands:
|
|
|
|
* exact - like `album__name__exact='Malibu'` (exact match)
|
|
* iexact - like `album__name__iexact='malibu'` (exact match case insensitive)
|
|
* contains - like `album__name__conatins='Mal'` (sql like)
|
|
* icontains - like `album__name__icontains='mal'` (sql like case insensitive)
|
|
* in - like `album__name__in=['Malibu', 'Barclay']` (sql in)
|
|
* gt - like `position__gt=3` (sql >)
|
|
* gte - like `position__gte=3` (sql >=)
|
|
* lt - like `position__lt=3` (sql <)
|
|
* lte - like `position__lte=3` (sql <=)
|
|
|
|
!!!note
|
|
`filter()`, `select_related()`, `limit()` and `offset()` returns a QueySet instance so you can chain them together.
|
|
|
|
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
|
|
|
### select_related(*args)
|
|
|
|
Allows to prefetch related models.
|
|
|
|
To fetch related model use `ForeignKey` names.
|
|
|
|
To chain related `Models` relation use double underscore.
|
|
|
|
```python
|
|
album = await Album.objects.select_related("tracks").all()
|
|
# will return album will all related tracks
|
|
```
|
|
|
|
You can provide a string or a list of strings
|
|
|
|
```python
|
|
classes = await SchoolClass.objects.select_related(
|
|
["teachers__category", "students"]).all()
|
|
# will return classes with teachers and teachers categories
|
|
# as well as classes students
|
|
```
|
|
|
|
!!!warning
|
|
If you set `ForeignKey` field as not nullable (so required) during
|
|
all queries the not nullable `Models` will be auto prefetched, even if you do not include them in select_related.
|
|
|
|
!!!note
|
|
`filter()`, `select_related()`, `limit()` and `offset()` returns a QueySet instance so you can chain them together.
|
|
|
|
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
|
|
|
### limit(int)
|
|
|
|
You can limit the results to desired number of rows.
|
|
|
|
```python
|
|
tracks = await Track.objects.limit(1).all()
|
|
# will return just one Track
|
|
```
|
|
|
|
!!!note
|
|
`filter()`, `select_related()`, `limit()` and `offset()` returns a QueySet instance so you can chain them together.
|
|
|
|
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
|
|
|
### offset(int)
|
|
|
|
You can also offset the results by desired number of rows.
|
|
|
|
```python
|
|
tracks = await Track.objects.offset(1).limit(1).all()
|
|
# will return just one Track, but this time the second one
|
|
```
|
|
|
|
!!!note
|
|
`filter()`, `select_related()`, `limit()` and `offset()` returns a QueySet instance so you can chain them together.
|
|
|
|
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()` |