Lesser-known methods in Django ORM

We all know Django provides ORM right out of the box thus preventing us from writing SQL queries. This mechanism has a lot of potentials. Most of us will be dealing only with the filter(), get(), all(), update() and delete() methods from the Django ORM.

But Django ORM provides a lot of other options in addition to this so we don’t miss the power of the traditional SQL queries. I will be covering the following methods in this article.

  1. exclude()
  2. values()
  3. values_list()
  4. select_related()
  5. order_by()
  6. exists()
  7. count()
  8. first() and last()
  9. in_bulk()
  10. explain()
  11. latest()
  12. earliest()

I will be using the following student table to provide examples for the above methods. This Student class is from the models.py file

The student table has a Foreign key relationship with the school table.

Let us get started.

1. exclude()

The first method is the exclude() method. This method will basically return us a query set excluding the value that we have given. I have 4 students in my student table. First, let me get them all using the all() method.

I do not want ‘Eva Smith’ to be present in the query set. So I can do something like this. I can call the exclude() method with her name on the Student model.

As you can see now she is excluded from the query set.

2. values()

The next method is the values() method. This method returns Python dictionaries, instead of a QuerySet object.

We can also retrieve only the fields that we require by providing the field names as arguments to the values() method. Let us say I need only the ‘id’ and ‘name’ of the students. I can do something like this.

3. values_list()

The values_list() method is similar to the values() method, but instead of returning dictionaries it returns tuples.

If we only need a single value like a list instead of a tuple we can pass an additional argument flat=True to the values_list method. If I want only name as a list I can do something like this.

Note: This will work only with a single field. If you provide more than one field you will get an error.

4. select_related()

This is one of the methods which I like very much. As I said my student table has a foreign key relationship to the school table. So in order to retrieve the school from a student, I can query like this.

First, the student table is queried with the student id to get a particular student. Then again in order to get the school, we perform an additional database lookup.

Note: Each foreign key relationship requires an additional database lookup.

For our simple example, this is not a problem, but in large databases with many foreign key relationships, the load on the database can be prohibitive.

We can use select_related() to improve database performance by retrieving all related data the first time the database is hit.

In this case, the school data is retrieved from the pre-fetched data while making the first query instead of querying the database again.

5. order_by()

The order_by() method changes the default ordering of the QuerySet. By default, the ordering is based on the primary key(id) field. If I want my QuerySet to be ordered based on names I can provide the names field to the order_by() method.

If I want my QuerySet to be ordered based on the names in ascending order I can do something like this.

If I want the names in descending order I can query the database like this.

The negative of the field name will do the trick.

6. exists()

The exists() method returns True if the returned QuerySet contains one or more objects, False if the QuerySet is empty.

My database has a student named Regina Johnson and so the exists() method returns True when called with the name as ‘Regina Johnson’ and False in other cases.

7. count()

The count() method counts the number of entries in the QuerySet. It can be used to count all objects in a database table.

Or used to count the number of objects returned by a query:

count() is functionally equivalent to using the aggregate() function, but it has a cleaner syntax, and is likely to be faster on large datasets.

8. first() and last()

The first() method returns the first element in the QuerySet.

The last() method will return the last element from the QuerySet.

Although the QuerySet is similar to the list you can retrieve the first element using an index like queryset[0], but you cannot retrieve the last element like queryset[-1]. This will throw an error. In this scenario, the last() method will come in handy.

9. in_bulk()

in_bulk() takes a list of id values and returns a dictionary mapping each id to an instance of the object with that id. If you don’t pass a list to the in_bulk() method, all objects will be returned.

Let us say I want to retrieve only students whose id is 1 and 4, I can do something like this.

Then I can access the object using the id as an index.

10. explain()

This method returns a string of the QuerySet’s execution plan. Used for analyzing query performance.

11. latest()

The latest() method is similar to the last() method. This method returns the latest object in the table based on the given field(s).

For example, if you have a blog model and you wish to get the latest modified blog post you can do something like this.

This is equivalent to,

The latest() method can take multiple field names as well.

Note: If you have set the ordering meta in your model the results may vary.

12. earliest()

The earliest() method is similar to the first() method and the opposite to the latest() method.

This will take multiple field names as well and returns the first record from the table.

Conclusion

Hope this article is helpful. Follow me for more cool articles on Python and Django. Happy coding!

References

https://docs.djangoproject.com/en/3.2/ref/models/querysets/

Python Developer | Django Developer | Python Enthusiast