From 0ebecc8610f4d5467e3db3186c95f109c7fc97a2 Mon Sep 17 00:00:00 2001 From: collerek Date: Fri, 14 Aug 2020 15:24:44 +0200 Subject: [PATCH] finish initial queries docs --- docs/queries.md | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/docs/queries.md b/docs/queries.md index e69de29..b931809 100644 --- a/docs/queries.md +++ b/docs/queries.md @@ -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()` \ No newline at end of file