Django ORM __in 但不是精确的,而是包含不区分大小写的?

Django ORM __in but instead of exact, contains case insensative?

我目前正在尝试使用 Django ORM 来查询 Recipe 模型的成分。

class Recipe(models.Model):
    account = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True, blank=True)
    name = models.TextField(null=True, blank=True)

class RecipeIngredients(models.Model):
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, null=True)
    ingredient = models.TextField(null=True, blank=True)

我目前所掌握的是


ingredients = ["eggs", "bacon", "potato"]
recipes = Recipe.objects.filter(
    recipeingredients__ingredient__in=ingredients
).alias(
    ningredient=Count('recipeingredients')
).filter(
    ningredient__gte=len(ingredients)
)

根据我对 的理解,这将 return 所有仅包含“鸡蛋”、“培根”和“土豆”但不包含“鸡蛋”或“炒鸡蛋”的项目。有没有办法调整它以让它搜索所有包含成分和不区分大小写的项目?

您可以创建条件析取,其中:

from django.db.models import Q

ingredients = ['eggs', 'bacon', 'potato']

recipes = Recipe.objects.filter(
    Q(
        *[<strong>('recipeingredients__ingredient__icontains', ingredient) for ingredient in ingredients</strong>],
        _connector=Q.OR
    )
).alias(
    ningredient=Count('recipeingredients')
).filter(
    ningredient__gte=len(ingredients)
)

一个潜在的问题可能是,如果查询是 eggs,并且两个成分匹配,例如 'white eggs''brown eggs',这些将算作 两个,因此另一种成分,如 bacon 可能不是成分,仍将是 QuerySet 的一部分,所以不幸的是,制作 QuerySet 并不容易完全匹配所有成分。

可能的解决方案可能是:

ingredients = ['eggs', 'bacon', 'potato']

recipes = Recipe.objects.all()

for ingredient in ingredients:
    recipes = recipes.filter(recipeingredients__ingredient__icontains=ingredient)

但这将使 n 加入 n 成分,因此对于大量 ingredients.