Django REST Filtering Tutorial - Filter Against URL (Part III)
Django REST Filtering Tutorial (5 Part Series)
Entrée
We saw in the previous part — django rest filtering tutorial part 2 how to filter querysets with the current user.
Let’s pickup where we left, but this time instead of current user we will the ability to filter against URL by any users we want.
Note
You can find the code we’re working on this tutorial series in this repository: django-rest-filtering-tutorial
You don’t need to download and setup the repository in order to follow this series, however I’d like to encorauge to do so, since while you play you learn better as always.
My example will be to filter authors
by user
#3, so my query will be
look like this:
# httpie
$ http :8000/authors/3
# or with curl
# $ curl http://localhost:8000/authors/3
[
{
"first_name": "Name3",
"full_name": "Name3 Surname3",
"id": 3,
"last_name": "Surname3",
"user": 3
}
]
Where 3 is the user’s id/pk
. If no user
provided in the URL, the
endpoint will just return all objects.
The Code
User ID
In order to achieve that we need to build our URL endpoint regular expressions like below:
|
|
In the first path (line 7-9), we return all objects.
In the second path (line 10-14), we catch user
by regex via Django’s path
converter. Django will assign it as key:value
map to View
’s kwargs
.
Info
In Django the below path converters are available by default:
str
- Matches any non-empty string, excluding the path separator,'/'
. This is the default if a converter isn’t included in the expression.int
- Matches zero or any positive integer. Returns anint
.slug
- Matches any slug string consisting of ASCII letters or numbers, plus the hyphen and underscore characters. For example,something-your-drf-1-endpoint-something
.uuid
- Matches a formatted UUID. To prevent multiple URLs from mapping to the same page, dashes must be included and letters must be lowercase. For example,075194d3-6885-417e-a8a8-6c931e272f00
. Returns aUUID
instance.path
- Matches any non-empty string, including the path separator,'/'
. This allows you to match against a complete URL path rather than just a segment of a URL path as withstr
.
Beside above pre-defined converters you can use your own regex if you need more
complex cases like r'^comments/(?:page-(?P<page_number>\d+)/)?$'
— if you are
really sure about it: xkcd regex.
Also you can also build your own path converter: custom path converters.
You can get more information about URL dispatchers
in offical Django
Documention: django URL dispatcher.
Accordingly our related view AuthorViewSet
will be like this:
|
|
In this view we override default get_queryset
method to get the user id
. If
no kwarg
provided in the URL
, we return the default queryset
(line 18)
which is Author.objects.all()
(line 11).
If you use python >= 3.8, you can make it cleaner with walrus operator
,
PEP 572:
|
|
If you want to see the User
and Author
model, you can look at the repo,
however for easy access I put them below as well. In order to examine them just
expand the below section.
User and Author model
User
model:
|
|
Author
model:
|
|
User Name
Instead of user id
, let’s filter by the name
of the user
:
$ http :8000/authors/UserName3
[
{
"first_name": "Name3",
"full_name": "Name3 Surname3",
"id": 3,
"last_name": "Surname3",
"user": 3
}
]
Update our urls.py:
|
|
And modify our views.py:
|
|
Any Name
Lastly, let’s change filtering by allowing to search the name
in any of the
below model field:
first_name
ofauthor
,last_name
ofauthor
,name
ofuser
,username
ofuser
Modify our views.py
to get the desired outputs:
|
|
For this complex filtering we take advantage of Q object with |
(OR
)
logical operator.
Conclusion
In this tutorial we learned how to filter against the URL with the variations of defining different set of filters and keyword arguments.
See you in the next part of this tutorial series.
All done!