【问题标题】:Combining filters for a Django queryset为 Django 查询集组合过滤器
【发布时间】:2019-11-09 18:31:40
【问题描述】:

假设我的模型看起来像这样:

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

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

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

再一次,这按预期工作。但是,问题是我有很多这些字段要过滤,而且组合的数量很大。如果它是一个空数组,是否有一些只是告诉我的查询集忽略过滤器?如果 geo_type 是空字符串或 null,它也应该忽略这些。希望我已经明白了我的观点。

感谢您的帮助。

【问题讨论】:

    标签: django django-models django-orm


    【解决方案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']
    )

    【讨论】:

      猜你喜欢
      • 2022-11-08
      • 2019-07-29
      • 1970-01-01
      • 2014-06-12
      • 2017-03-28
      • 1970-01-01
      • 2020-08-22
      • 2019-04-15
      相关资源
      最近更新 更多