Django的。 ORM按功能的关键字参数过滤

时间:2017-01-10 19:16:18

标签: python django filter orm parameter-passing

我正在尝试从数据库中提取一些记录(关于杂志)以创建包含统计数据的表格。按时间段和杂志名称进行提取。这是我目前的代码,但我认为它不够干,原因有两个:

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)

但我不知道如何。

2 个答案:

答案 0 :(得分:1)

你可以这样做,假设参数只是被遗漏而没有明确地传递为def get_statistics(**kwargs): return Magazines.objects.filter(**kwargs)

kwargs

.filter(**kwargs)将是一个仅包含显式传入的关键字参数的dict。filter()将这些参数解压缩为传递给{{1}}的关键字参数。

答案 1 :(得分: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传递给过滤方法的情况下才有效。