5

I'm working with a query that looks like so:

    filters = Q(is_default = False)
    # Build the excludes and filters dynamically 
    if cut:
        filters = filters & Q(mailbagstats__num_letters2__gt = int(cut) )

Given the filters Q query, can I pop one of the queries?

I'd like to remove the Q(mailbagstats__num_letters2__gt= int(cut) ) query from this Q query for a new filter down the line.

Normally, I use lists and reduce but this one is constructed via Q() & Q() so I'm not sure how to modify it.

Thanks for any input you might have!

Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245

2 Answers2

6

You can pop them:

>>> filter = Q(a=True)
>>> filter = filter & Q(b=True)
>>> filter.children
[('a', True), ('b', True)]
>>> filter.children.pop()
('b', True)
>>> filter.children
[('a', True)]
César
  • 9,939
  • 6
  • 53
  • 74
1

Why don't you work with lists and made the filter at the end?

filters = []
filters.append(Q(is_default = False))
# Build the excludes and filters dynamically 
if cut:
    filters.append(Q(mailbagstats__num_letters2__gt = int(cut)))

# I want to pop the last one
filters.pop()

# build the filter before making the query
# Note that this call will remove an element from the filters list
filters_for_query = reduce(lambda a, x: a & x, filters, filters.pop())

Model.objects.filter(filters_for_query)
santiagobasulto
  • 11,320
  • 11
  • 64
  • 88