Search code examples
djangodjango-querysetdjango-oscar

Queryset filter using Case/When for Model field, not field value


I would like to combine two querysets, or better, make only one using the Case/When syntax for a specific case.

I have seen in the documentation that it can be use for queryset filtering, not only annotate, which is exactly what I need. However, I want to use the Case/When for the model field itself, not the value of the field.

The project is an e-commerce, I use django-oscar so the models are quite big to post them here. The thing to know is that a basket line refers to a product, and a product can either be parent, child or standalone.

Here is my code :

self.in_stock_lines = basket.lines.filter(product__product_class__track_stock=True, is_customized=False)

Thing is, if the basket line relates to a product being a child, the field I must filter on is product__parent__product_class__track_stock, whereas if it relates to a standalone product (having not parent), it stays product__product_class__track_stock as in my initial queryset.

Is there a way to do this ? Or do I have no choice but combine the two querysets using itertools.chain() for example ?


Solution

  • You can use Q objects for that.

    from django.db.models import Q
    
    basket.lines.filter(
      Q(product_parent__isnull=True, product__product_class__track_stock=True) | 
      Q(product__parent__product_class__track_stock=True), is_customized=False)