为 Django 查询集组合过滤器
Combining filters for a Django queryset
假设我有这样的模型:
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 参数来过滤披萨 table。例如,有一次我可能会得到以下信息:
{
"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,它也应该忽略这些。希望我已经明白我的意思了。
感谢您的帮助。
您可以省略空列表,例如通过制作辅助函数:
def filter_ignore_if_empty(qs, **kwargs):
return qs.filter(**{k: v for k, v in kwargs.items() <b>if v != []</b>})
然后过滤:
<b>filter_ignore_if_empty(</b>
Pizza.objects.all(),
sauces__in=url_params['sauces'],
toppings__in=url_params['toppings'],
geo_type=url_params['geo_type']
<b>)</b>
假设我有这样的模型:
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 参数来过滤披萨 table。例如,有一次我可能会得到以下信息:
{
"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,它也应该忽略这些。希望我已经明白我的意思了。
感谢您的帮助。
您可以省略空列表,例如通过制作辅助函数:
def filter_ignore_if_empty(qs, **kwargs):
return qs.filter(**{k: v for k, v in kwargs.items() <b>if v != []</b>})
然后过滤:
<b>filter_ignore_if_empty(</b>
Pizza.objects.all(),
sauces__in=url_params['sauces'],
toppings__in=url_params['toppings'],
geo_type=url_params['geo_type']
<b>)</b>