Monday, 1 June 2015

Django - Model Operations: Part 2

To learn about inserting records via Django's ORM refer to Django - Model Operations: Part 1. In this article we will discuss the querying ability of Django's ORM.

Manager

Each model class in Django has an attached attribute objects which is an instance of Manager class. This works as gateway for obtaining information from the database by firing different querys. It supports the following 4 methods.

all: It is like SELECT *. It returns a QuerySet containing all the database records for the model in question

get: Obtain a single record matching the given criteria (or raise an error if there are either no matches or more than one)

filter: Return a QuerySet containing the model records matching specific criteria

exclude: Inverse of filter - find records that don't match the criteria.


Following illustrate use cases for the above methods.
>>> Actor.objects.all()
[<Actor: Aamir Khan>, <Actor: Salman Khan>, <Actor: Akshay Khanna>, <Actor: Shahrukh Khan>, <Actor: Aishwarya Rai>, <Actor: Zarine Khan>]
>>> Actor.objects.get(pk=4)
<Actor: Shahrukh Khan>
>>> Actor.objects.filter(last_name='Khan')
[<Actor: Aamir Khan>, <Actor: Salman Khan>, <Actor: Shahrukh Khan>, <Actor: Zarine Khan>]
>>> Actor.objects.exclude(last_name='Khan')
[<Actor: Akshay Khanna>, <Actor: Aishwarya Rai>]

QuerySet

The return type of get(), filter() and exclude() methods is QuerySet. It is like result of a SELECT query which consists of list of model instances. In Django, a QuerySet instance is much more powerful than a simple list. Manager instance opens the gate with the db and gives QuerySet back. This QuerySet can be stored in a variable and further operations can be performed over it.

Following example demonstrates how a QuerySet can be used as database query. It also depicts three string filtering operations viz.
  • __startswith - like 'A%'
  • __contains - like '%A%'
  • __endswith - like '%A'
>>> all_khans = Actor.objects.filter(last_name='Khan')
>>> all_khans.filter(first_name__startswith='S')
[<Actor: Salman Khan>, <Actor: Shahrukh Khan>]
>>> all_khans.filter(first_name__contains='m')
[<Actor: Aamir Khan>, <Actor: Salman Khan>]
>>> all_khans.filter(first_name__endswith='h')
[<Actor: Shahrukh Khan>]
>>> all_khans.filter(first_name__contains='m').filter(first_name__endswith='r')
[<Actor: Aamir Khan>]
>>> all_khans.filter(first_name__contains='m').filter(first_name__endswith='n')
[<Actor: Salman Khan>]

All the four methods all(), get(), filter() and exclude() are also supported by QuerySet.

Another method which QuerySet supports is order_by()
>>> movies = Movie.objects.all()
>>> movies.order_by('-release_date')
[<Movie: Taare Zameen Par>, <Movie: Kal Ho Na Ho>]
>>> movies.order_by('release_date')
[<Movie: Kal Ho Na Ho>, <Movie: Taare Zameen Par>]

Note for descending order, start field name with dash (-)

Movie refers to Production House. Now if you wish to order the result by the banner (name) of production houses,
>>> movies.order_by('production_house__banner')
[<Movie: Taare Zameen Par>, <Movie: Kal Ho Na Ho>]

Take content from URL -
https://docs.djangoproject.com/en/1.8/ref/models/querysets/

Learn about aggregation & create a new post
https://docs.djangoproject.com/en/1.8/topics/db/aggregation/