Фильтр моделей Django с использованием списков параметров полей

Я хотел бы иметь возможность передавать любое количество полей и значений в функцию для идентификации соответствующих строк:

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})

То, что я пытаюсь сделать выше, явно не работает! Я знаю, что я также могу использовать exec(), чтобы получить то, что я хочу:

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'})

Но я думаю, что должен существовать более естественный способ распаковки содержимого словаря непосредственно в filter().

Любое руководство по этому вопросу приветствуется.

Вы должны распаковать словарь в функции так **kwargs вместо kwargs:

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

Тогда вы можете использовать это, передав словарь:

find_player({defender:True, goalkeeper:True})
find_player({defender:True, attacker:False})
find_player({defender:False})
Вернуться на верх