Popping a query from django Q query?
Asked Answered
F

2

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!

Farro answered 11/9, 2012 at 21:5 Comment(0)
P
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)]
Poop answered 11/9, 2012 at 21:13 Comment(1)
Very nice! Thanks! I will write a function that takes a key and iterates through the list (children requires recursion too) and pops them!Plage
G
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)
Graze answered 11/9, 2012 at 21:13 Comment(6)
The children attribute is a listInspissate
Yes, you're right. I was just proposing other solution. I like to handle lists. You're answer is better for this particular question. +1 ;)Graze
No, it's okay. I wasn't saying my answer was better. Just pointing out that there is no need for a new list since you already have one :)Inspissate
And hey! I hope we can beat Argentina tonight! xDInspissate
I normally do lists, but in this case the code I'm working with uses the other syntax.Plage
Haha, @César, It'll be hard for us. You've got a pretty strong team. And, yes, your answer is better. It goes straight to the point.Graze

© 2022 - 2024 — McMap. All rights reserved.