2017-01-10 5 views
0

Я пытаюсь извлечь некоторые записи (о журналах) из базы данных, чтобы создать таблицу со статистикой. Добыча производится по времени и названию магазина. Вот код, который я в настоящее время, но я предполагаю, что это не DRY достаточно по двум причинам:Django. ORM filter по аргументу ключевого слова function

def get_statistic(date__gte=None, date__lte=None, name=None): 
    magazines_qs = Magazines.objects.all() 

    #1 move filters to "for" 
    #2 get rid of "if" statement (may be by setting default values which 
    #        makes filter equal to .all() method) 
    if date__gte: 
     magazines_qs = magazines_qs.filter(date__gte=date__gte) 
    if date__lte: 
     magazines_qs = magazines_qs.filter(date__lte=date__lte) 
    if offer: 
     magazines_qs = magazines_qs.filter(name=name) 

Я полагаю, что можно получить что-то вроде:

def get_statistic(date__gte=None, date__lte=None, name=None): 
    magazines_qs = Magazines.objects.all() 

    for filter in arguments() 
     magazines_qs = magazines_qs.filter(filter) 

Но я не секрет производства.

ответ

0

Чтобы показать решение, которое ближе к исходному коду, поэтому он принимает только определенный набор аргументов (это комбинация из двух существующих ответов):

def get_statistic(date__gte=None, date__lte=None, name=None): 
    filter_args = {'date__gte': some_date, 'date__lte': some_other_date, 'name': name} 
    filter_args = dict((k,v) for k,v in filter_args.iteritems() if v is not None) 
    magazines_qs = Magazines.objects.filter(**filter_args) 

Примечание: Это, конечно, работает только в том случае, если у вас нет случая, когда вы полагаетесь на метод None, который передается методу фильтра.

1

Вы можете сделать это, предполагая, что параметры только когда-либо опущены, а не явно передается как None:.

def get_statistics(**kwargs): 
    return Magazines.objects.filter(**kwargs) 

kwargs будет ДИКТ, содержащий только ключевые аргументы, которые явно передаются в .filter(**kwargs) распаковывает их в аргументы ключевого слова, которые передаются в filter().