#DjangoTip — Playing with Querysets

Hey, today the #DjangoTip will be playing with querysets.

First and foremost, let me begin saying that there’s always other ways to write code, my way could not be yours and that’s totally fine! My code shouldn’t be considered the source of truth, this is only alternatives to play with. Have fun!


https://github.com/LucasMagnum/django-tip-01/blob/master/app/products/models.py

Product Model

Here we have our simple model and two querysets.

This will be the model used in all the examples bellow, so we can always come back here and read again.

We have two querysets:

adult_products = Product.objects.filter(is_adult=True)
active_products = Product.objects.filter(is_active=True)

That’s it, now let’s start playing with them.

1. How we can see what SQL statement these querysets will be transformed into database?

The simple way to see is print the query attribute from QuerySet .

Showing SQL statements from QuerySet

Note: When we use aggregate , get or other method which return a single value, this query attribute may not be present.

Furthermore we can use connections to see which queries is running into database: connections example.

2. How can we combine these two querysets?

We have adult_products and active_products, and we want the products that are active and are adult at the same time, how can we do it?

Intersection

We can use intersection method or the bitwise operation AND:

https://github.com/LucasMagnum/django-tip-01/blob/master/app/products/tests.py#L26

That’s it! Now we have all active and adult products =)

That’s not a big deal, we know! We can probably think: “Hmmm, ok! What if we want both active products and adult products in the same result?”

Union

We can use union method or the bitwise operation OR:

https://github.com/LucasMagnum/django-tip-01/blob/master/app/products/tests.py#L36

WOW! Now we have all products together =D

But we still can think: “Hmm, it’s good, but I’m not satisfied yet. What if we want the products that are active but aren’t adult?”

Difference

We can use difference method:

>> active_but_not_adult = active_products.difference(adult_products)

And once more, we think: “Yeah, it seems to be good, but what if we want the adult products that aren’t active?”

We can use difference again, just using the adult queryset:

>> adult_but_not_active = adult_products.difference(active_products)

Now we have all the adult products that aren’t active ;D

TL;DR:

  • We can use query to see the SQL statements from querysets
  • We can use union or | to combine two querysets and get the OR behaviour
  • We can use intersection or & to combine two querysets and get the AND behaviour
  • We can use difference method on queryset to get items in first but not in second queryset

All code can be found in https://github.com/LucasMagnum/django-tip-01

Let me know if you want to see some specific tip about Django (:

That’s it! This is our #DjangoTip today! See you later! ❤