构建具有动态字段数的 Django 优雅过滤器
Build a Django elegant filter with dynamic number of fields
我有一个 Django 模型,我正在为它做一个视图,过滤结果。
models.py:
Ingredient(models.Model):
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=False)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, null=False)
name = models.CharField(max_length=100, null=False, blank=False)
cost = models.DecimalField(max_digits=14, decimal_places=2, null=False)
现在的重点是搜索表单(除了 account
之外的所有字段),其中 none 个字段是必需的,您可以仅按一个或两个字段进行过滤或者他们三个。
问题是我做不到:
Ingredient.objects.filter(account=account, brand=brand, name=name, cost=cost)
...因为可以发送品牌、名称和费用 empty/null
如何在不为每种过滤可能性制作过滤行代码的情况下解决这个问题?
我们可以创建一个效用函数来过滤掉 None
。例如:
from django.db.models import Q
def filter_without_none(**kwargs):
return Q(**{k: v for k, v in kwargs.items() if v is not None and v != ''})
现在我们可以过滤:
Ingredient.objects.filter(
<b>filter_without_none(</b>account=account, brand=brand, name=name, cost=cost<b>)</b>
)
如果像 account
、brand
、and/or name
这样的一个(或多个)值是 None
,这些将 不被考虑过滤。
我有一个 Django 模型,我正在为它做一个视图,过滤结果。
models.py:
Ingredient(models.Model):
account = models.ForeignKey(Account, on_delete=models.CASCADE, null=False)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, null=False)
name = models.CharField(max_length=100, null=False, blank=False)
cost = models.DecimalField(max_digits=14, decimal_places=2, null=False)
现在的重点是搜索表单(除了 account
之外的所有字段),其中 none 个字段是必需的,您可以仅按一个或两个字段进行过滤或者他们三个。
问题是我做不到:
Ingredient.objects.filter(account=account, brand=brand, name=name, cost=cost)
...因为可以发送品牌、名称和费用 empty/null
如何在不为每种过滤可能性制作过滤行代码的情况下解决这个问题?
我们可以创建一个效用函数来过滤掉 None
。例如:
from django.db.models import Q
def filter_without_none(**kwargs):
return Q(**{k: v for k, v in kwargs.items() if v is not None and v != ''})
现在我们可以过滤:
Ingredient.objects.filter(
<b>filter_without_none(</b>account=account, brand=brand, name=name, cost=cost<b>)</b>
)
如果像 account
、brand
、and/or name
这样的一个(或多个)值是 None
,这些将 不被考虑过滤。