Search code examples
pythondjangoormiterationpython-itertools

How to do multiple exclude commands using itertools.chain in Django?


Suppose I wanna run the exclude command repeatedly getting variables from exclude_list e.g. ['aa', 'ab' 'ac'].

I can do that using a loop:

for exclude_value in exclude_list:
     myQueryset.exclude(variable__startswith=exclude_value)

However, I'd like to do that using the itertools.chain command as I've read it is capable of doing so. Any suggestions?


Solution

  • What you are doing is the correct approach - except for one small detail, you aren't retaining the excludes. Django querysets are lazily evaluated, so running through a loop and continually chaining won't do anything, right up until you try to access something from the set.

    If you do this:

    qs = MyModel.objects
    for exclude_value in exclude_list:
        qs = qs.exclude(variable__startswith=exclude_value)
    
    qs = None
    

    The database is never hit.

    So do this:

    qs = MyModel.objects
    for exclude_value in exclude_list:
        qs = qs.exclude(variable__startswith=exclude_value)
    
    qs.count() # Or whatever you want the queryset for
    

    and you should be fine, if/when you are experience database slowdown, which ill likely be because of the large number of freetext expressions in a query, then do some profiling, then you can find an efficiency.

    But I'd wager the above code would be sufficient for your needs.