组合Django查询集的过滤器

时间:2019-11-09 18:31:40

标签: django django-models django-orm

让我们说我的模型看起来像这样:

class Sauce(models.Model):
    ...

class Topping(models.Model):
    ...

class Pizza(models.Model):
    sauces = models.ManyToManyField(Sauce, related_name='pizzas')
    toppings = models.ManyToManyField(Topping, related_name='pizzas')
    geo_type = models.CharField(max_length=50, choices=(('NY', 'New York'), ('IT', 'Italy')))

现在,我有一个端点,该端点接受用于过滤披萨表的URL参数。例如,有一次我可能得到以下信息:

{
    "sauces": [1, 4],
    "toppings": [4, 7],
    "geo_type": "NY"
}

使用此代码,我将使用以下代码进行过滤:

Pizza.objects.filter(sauces__in=url_params["sauces"], toppings__in=url_params["toppings"], geo_type=url_params["geo_type"])

这将很好地工作。但是,有时我可能会得到如下所示的URL参数:

{
    "sauces": [],
    "toppings": [4, 7],
    "geo_type": "NY"
}

注意调味汁参数的空数组。这意味着对于此请求,我不在乎酱料,它可以是任何东西。现在查询将是这样的:

Pizza.objects.filter(toppings__in=url_params["toppings"], geo_type=url_params["geo_type"])

再次,这将按预期方式工作。但是,问题是我要过滤很多这些字段,并且组合的数量巨大。是否有一些要告诉我的查询集忽略过滤器(如果它是空数组)?并且,如果geo_type为空字符串或null,则也应忽略它们。希望我已经明白了。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您可以省略空白列表,例如通过创建一个辅助函数:

def filter_ignore_if_empty(qs, **kwargs):
    return qs.filter(**{k: v for k, v in kwargs.items() if v != []})

,然后使用:

filter_ignore_if_empty(
    Pizza.objects.all(),
    sauces__in=url_params['sauces'],
    toppings__in=url_params['toppings'],
    geo_type=url_params['geo_type']
)