justajolt
justajolt

Reputation: 151

Filter Django Models using lists of field parameters

I'd like to be able to pass any number of fields and values into a function to identify relevant rows:

models.py

class Player(models.Model):
    name = CharField(max_length = 50, default = 'Ronaldo')
    defender = BooleanField(default = False)
    midfielder = BooleanField(default = False)
    attacker = BooleanField(default = False)
    goalkeeper = BooleanField(default = False)

views.py

def find_player(**kwargs):#to be used in some view
    players = Player.objects.filters(kwargs).all()
    for player in players:
        #do something with player...

find_player({defender:True, goalkeeper:True})#selects rows with players who defend and play in goal
find_player({defender:True, attacker:False})#...
find_player({defender:False})

What I'm trying to do above clearly doesn't work! I know that I could also use exec() to get what I want:

def find_player(string_of_params):
    players = exec(Player.objects.filters(string_of_params).all())
    for player in players:
        print(player)

find_player('defender=True, goalkeeper=True')#prints rows with players who can defend and go in goal
find_player('defender=True, attacker=False')#...
find_player('defender=False'})

But I think there has to be a more natural way of unpacking the contents of a dictionary directly into filter().

Any guidance on this welcome.

Upvotes: 1

Views: 50

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476729

You should unpack the dictionary in the function so **kwargs instead of kwargs:

#               ↓ no double asterisk
def find_player(kwargs):
    #                                ↓↓ double asterisk
    players = Player.objects.filters(**kwargs).all()
    # …

Then you can use this by passing a dictionary:

find_player({defender:True, goalkeeper:True})
find_player({defender:True, attacker:False})
find_player({defender:False})

Upvotes: 1

Related Questions