finish initial queries docs

This commit is contained in:
collerek
2020-08-14 15:24:44 +02:00
parent c6b4f69c4d
commit 0ebecc8610

View File

@ -0,0 +1,156 @@
# 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 orm 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()`