Django Models Part 3 (Model Manager, QuerySet, Lookups)

Model Manager
- A
Manageris the interface through which we perform ORMs in Django models - By Default, Django automatically adds a
Managerwith a name ofobjects. This is the reason we are able to useobjectsand query to our Modelseg: Model.objects.all() - We can always create a new Manager and add to our model. We can customize ORM methods or add some more functionality in our Manager for data query
- Atleast one Manager should exist in every models
Example to change rename default objects in our model
from django.db import models
class Info(models.Model):
name = models.CharField(max_length=100)
data = models.Manager()
# Info.objects.all() will not work but Info.data.all() will work
QuerySet
- QuerySet can be defined as a collection of Objects (model objects)
- Until and unless you do something to evaluate a QuerySet
(loop, slice with increments,...), it doesn't hit your database. So, we call it by saying QuerSet is Lazy
Let's take an example of basic model which we will be using in this tutorial
- All, methods, customizations will be done on basis of this model below
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
QuerySet Methods
filter()
- Returns a new QuerySet, list of objects that matches the given lookup criteria
- To return list of
userswhoseage=10, we can doUser.objects.filter(age=10);qs = User.objects.filter(age=10) for u in qs: print(u.name, u.age) - Multiple arguments are joined by
ANDclause when crafting an SQL query - So,
User.objects.filter(age=10, name="John")will return list ofuserswhoseageis10ANDwhosenameisJohn - If you need to join arguments with
ORyou can useQobjects. e.g. This example will return list of users whose name isJohnORHarryfrom django.db.models import Q qs = User.objects.filter(Q(name='John') | Q(name='Harry'))
exclude()
- Returns a new Queryset, list of objects that do not match the given lookup criteria
- Same like
filter()multiple arguments/parameters are joined byANDclause User.objects.exclude(age=20)will return list of users whoseageis not20
order_by()
- Used to perform some ordering for the return QuerySet list
If you have set default ordering for your models, you don't even have to use this method to order your
QuerySet, because the results returned byQuerySetare ordered automatically by the ordering tuple given by theorderingoption in modelsMetaclass User(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() class Meta: ordering = ['-age'] # - negative sign for descending order and # no sign for asc orderUser.objects.filter(age=10)on this model will return the list of users whoseageis10in descending order ofageUser.objects.filter(age=10).order_by('age')on this model will return the list of users whoseageis10in ascending order ofageUser.objects.order_by('-name')will return list of users in descending order
none()
- Calling
none()will create aQuerySetthat will never return any objects - This doesn't return any data, so this can be used in place where we need a valid
QuerySetbut no data - calling
none()will not hit database - e.g
User.objects.none()
- Calling
all()
- This method is the simplest way to retrieve all objects from the model
User.objects.all()will return list of every users/objects
Database ORM methods which do not return a QuerySet
- get()
User.objects.get(id=1)will return the row/object whoseidis1
- create()
User.objects.create(name="Peter",age=25)will create a new object/record in database and return that object
- first()
User.objects.filter(id=10).first()will return the first row/object whoseidis10
- last()
User.objects.filter(id=10).last()will return the last row/object whoseidis10
- delete()
User.objects.filter(id=10).delete()will delete objects/rows whoseidis10. This works like a bulk delete- You can also perform
delete()on model single objects like the objects obtained fromget()first()last()methods. This works like a single object delete
- count()
User.objects.filter(id=10).count()will return total number of users/objects whoseidis10
Field Lookups
- Field lookups are used to specify meaning to the SQL
WHEREclause - These lookups are crafted and attached with the fields when performing an ORM queries
- It looks like
field_[LookupType]=value[note the double underscores]
Lookups Types
exact (also a default lookup)
- An exact Match
User.objects.filter(name__exact="Peter")would generateSQL: select .... where name="Peter"and returns the objects/rows whose name isPeterIf we do not provide a lookup like in the above
QuerySetmethod examples, Django automatically usesexactlookup. This is the reason our ORMs were working even when we didn't pass any lookups- Thus,
User.objects.filter(name__exact="Peter")andUser.objects.filter(name="Peter")QuerySet is practically the same
iexact
- Case insensitive match
User.objects.filter(name__iexact="peter")would return QuerySet of the list of users whose name ispeter(case insensitive)i.e:peter,Peter,PeTeR,peteRe.t.c
contains
- Case sensitive containment
User.objects.filter(name__contains="a")would generateSQL: select ..... where name like '%a%'and would return QuerySet of list of users whosenamecontains/includesa
icontains
- Similar to
containsbut case-insensitive
- Similar to
gt
- greater than
User.objects.filter(age_gt=10)would return QuerySet of list of users whose age is greater than 10 i.e 11,12,13,.......
gte
- greater than or equal to
User.objects.filter(age_gte=10)would return QuerySet of list of users whose age is greater than or equals to 10 i.e 10,11,12,13,.......
lt
- less than
User.objects.filter(age_lt=10)would return QuerySet of list of users whose age is less than 10 i.e 9,8,7,......
lte
- less than or equal to
User.objects.filter(age_lte=10)would return QuerySet of list of users whose age is less than or equals to 10 i.e 10,9,8,7,.....
There are other plenty of inbuilts lookups. To name some of them;
instartswithistartswithrange






