This is part of the series Django For Beginners we are going to see about apps in app and we will see about models in django in this part.
In this post we are going to learn a lot queries in django. I recommend you to read last post so as it will be easy to understand context of this post , now let’s get started.
These are the models
which we are going to use for most part in this post,
from django.db import models
from django.utils import timezone
from djnago.contrib.auth.models import User
class Post(models.Model)
title = models.CharField(max_length=250)
created_at = models.DateTimeField(default=timezone.now)
author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name="author")
likes = models.ManyToManyField(User, blank=True, related_name="likes")
dislikes = models.ManyToManyField(User, blank=True, related_name="dislikes")
likes_count = models.PositiveIntegerField(default=0)
dislikes_count = models.PositiveIntegerField(default=0)
rating = models.DecimalField(max_digits=4, decimal_places=2)
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
liked_posts = models.ManyToManyField(Post, blank=True, related_name="liked_posts")
disliked_posts = models.ManyToManyField(Post, blank=True, related_name="disliked_posts")
If you understand all about models then head on to the query section by clicking here.
Models Explanations
Now let me explain what have I done above,
I have created 2 models, Post
and Author
, and we have added many fields to it, let’s see them one by one,
likes
, dislikes
, liked_books
, disliked_books
: I have merged because they have save field that is Many To Many Field
it is used to create many to many relationship.
created_at
: It is a datetime field and it used to store date and time in database. I have set it default value to timezone.now
so as to get current time and date and store it, the same could be achieved by using auto_now=True
but it does not give flexibility to us.
author
: It is a ForeignKey
and is used to denote One to Many Relationship
. The model is its first argument but as you may have seen I passed the first value as name of the model that is because as model is below that model it cannot find it as python interprets code line by line. So to solve this problem we pass name of model as a argument and it works thanks to django.
likes_count
, dislikes_count
: They use PositiveIntegerField
it is same as IntegerField
somewhat but it only supports values from 0
to 922337203685477580
while IntegerField
supports values from from -2147483648
to 2147483647
. Most of times PositiveIntegerField
get’s the work and works for validation to o I like to use it more above IntegerField
unless I need support for negative values.
user
: It is an OneToOneField
and is used to create one to one relationship
, what is essentially means that the model passed to it as an argument will only have one model with the model to whose field is as OneToOneField
.
title
: It is a CharField
and is used to store simple character data.
If you don’t know know about models I suggest you take a read about Models in django at 👨💻 Django For Beginners - Models in Django ( Part 5 ). It will definitely help you.
Yay Queries !
Finally we are going to see about queries in django, I am going to import all models at once and not again and again so keep his in mind if you are going to try these quries on you computer.
from .models import Post, Author
Get All
To get all data of the model we use this query, it is not used most often as it costs a lot of resources if data is large and it is always a good practice to limit the query results which we will see how to do after this,
all_posts = Post.objects.all()
syntax = ModelName.objects.all()
Limit Query Results
To limit results of any query we add [ start_count : end_count ]
to get results from start_count
and end_count
you can also use [ : end_count ]
to get results from 0
to end_count
. Let’s see an example,
only_five_posts = Post.objects.all()[:4]
The above query will give 5
results only as index start from 0
and till 4
it would be five results.
Get Query
There is situation many times when we want to retrieve only one result from the query with exact match of fields for such situations we use get query, let me show you an example,
one_post = Post.objects.get(id=1)
syntax = ModelName.objects.get( pass_keyword_arguments )
Getting Many Search Results
Above we have seen how to retrieve one result but you can also search for exact filed value to obtain more than one result, let’s see an example,
one_post = Post.objects.filter(likes_count=10)
For such situations we use filter
method.
syntax = ModelName.objects.filter( pass_keyword_arguments )
Getting Like Query Search Results
To obtain results let’s say for search we cannot use exact match as to provide better results so for such time we use LIKE
Query in SQL
and to use the same in django we use either __contains
or __icontains
, let me show you how ,
posts = Post.objects.filter(title__contains="The Title Not Exact")
posts = Post.objects.filter(title__icontains="The Title Not Exact")
To use LIKE
query on a filed we add __contains
or __icontains
to its end as you can see above and then continue it.
Now you may ask what is difference between __contains
and __icontains
, it is not much just the difference is that __contains
search results for same case on the field, whereas __icontains
search results irrespective of case on the field.
Filtering by Date And Time
Using Date
You can also filters posts by date using this syntax by year created_at_date__year=2006
, you can also use created_at_gte=datetime.date.today()
by using datetime module more than or equal to ( >= ) Query
, this format created_at_date__lte='2006-01-01'
which creates less_than or equal to ( <= ) Query
.
posts = Post.objects.filter(`created_at_lte=datetime.date.today()`)
Filtering by Foreign Key
We can also use foreign key to filter objects we can, let’s see an example, let’s us filter posts by author and then retrieve it all,
author = Author.objects.get(id=1)
posts = Post.objects.filter(author=author)
It will get author of id
1 and then we have filtered posts, by passing query where author
variable equals to author
filed in the Post
model. Under the hood django will gets author id and then queries post table where author
of post equals to the id
of the author
object we have passed. In database foreign keys are store as integer
values which are ids
of the related author
model.
Filtering by Many To Many Field
Many to many filed is a bit different then the fields than the other fields we have seen till now as it is not a filed instead it is a table itself. It has two fields which are ids
of the related models in two tables.
Let’s understand it by an example,
First let’s understand how to create a entry in many to many field in django. It is very simple to do,
some_author = Author.objects.get(id=50)
some_post = Post.objects.get(id=50)
some_author.liked_posts.add(some_post)
some_author.save()
This will do the thing the syntax is kind of like this model.many_to_many_field.add(related_model)
, and even if the many to many field has related_model
already created it will not throw any error and will work fine, the same applies when we remove object from many to many field.
some_author = Author.objects.get(id=50)
some_post = Post.objects.get(id=50)
some_author.liked_posts.remove(some_post)
some_author.save()
The syntax is same as above the only difference being that the instead of add
we use remove
.
To get all objects in many to many filed we use .all()
method on the field. See the example below,
some_author = Author.objects.get(id=50)
some_post = Post.objects.get(id=50)
all_liked_post = some_author.liked_posts.all()
Filtering By Integers
You can also filter integer filed and it should be obvious by now, let’s see the examples and it should be clear and there is nothing fancy in it.
more_liked_posts = Post.objects.all(likes_count >= 500)
less_liked_posts = Post.objects.all(likes_count <= 500)
some_posts = Post.objects.all(likes_count = 500)
Using Order By
We can order our query results by using order_by
method at the end of the query, let’s see an example,
posts = Post.objects.all().order_by('likes_count', '-created_at')
more_posts = Post.objects.all().order_by('likes_count', '-created_at')[:100]
We pass the field name in order_by()
as string. The order by which the names of the fields are passed in order by are passed the they are ordered in the same way . It is useful when you want order results by more than field. We can also limit the results by using limit thing, I am not sure what to call it, this one [:100]
.
Hope you guys like, if you share this it would be amazing and it would be appreciated a lot. It takes a lot of effort to write such articles so a share would be great.
Also check out my other articles. Hope you like them too. 😊