DEV Community

Optimize the Django ORM

Adam Hill on December 06, 2018

Recently, I have been optimizing some functions that were slower than expected. As with most MVPs, the initial iteration was to get something worki...
Collapse
 
jdelgit profile image
jdelgit

Nice post, I've recently been using Q-objects for sql, makes building dynamics queries a lot easier, for example :

def foo(username='',option_1=false, option_2=true):
    basic_query= Q(user=username)
    if option_1:
      basic_query.add( (Q(field_a=bar)| Q(field_a=baz, basic_query.connector)
    elif option_2:
      basic_query.add( (Q(field_a=bar) & Q(field_a=baz, basic_query.connector)

    foo_model.objects.filter(basic_query)

    .....
    .....
    .....    
Enter fullscreen mode Exit fullscreen mode
Collapse
 
adamghill profile image
Adam Hill

Yep!

One additional trick that I haven't seen referenced many places is to use a dictionary for dynamic queries. This trick only works for ANDs, though. The dictionary should use the column name as the keyword, and the lookup as the dictionary value. Then, you can expand the dictionary into kwargs for the filter query with a double-splat (i.e. .filter(**{})).

A silly example, but at least it gives you the idea:

filters = {
    "author__name": "Edgar Allen Poe",
    "title__startswith": "The ",
}

poe_books_that_start_with_the = Book.objects.filter(**filters)
Collapse
 
adamghill profile image
Adam Hill

github.com/chrisseto/django-include was also mentioned by a friend on Twitter for more performant many-to-x relation traversal. I haven't used it, but adding it here in case it's helpful.

Collapse
 
beesnotincluded profile image
beesnotincluded

Great overview. Thanks