version with pydantic inheritance passing all the tests
This commit is contained in:
156
docs/queries.md
Normal file
156
docs/queries.md
Normal 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 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()`
|
||||
Reference in New Issue
Block a user