Django ORM __in, но вместо exact содержит 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)
)

Насколько я понимаю этот ответ, это вернет все товары, которые содержат только "яйца", "бекон" и "картофель", но не скажет Eggs или Scrambled EGGS. Можно ли как-то настроить поиск всех элементов, содержащих указанные ингредиенты и нечувствительных к регистру?

Вы можете создать дизъюнкцию условий, с:

from django.db.models import Q

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

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

Потенциальной проблемой может быть то, что если запрос будет eggs, и два ингредиента совпадут, например 'white eggs' и 'brown eggs', они будут считаться как two, и поэтому другой ингредиент, например bacon, может не быть ингредиентом, и все равно будет частью QuerySet, поэтому, к сожалению, нелегко сделать QuerySet, который точно соответствует всем ингредиентам.

Потенциальное решение может быть следующим:

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

recipes = Recipe.objects.all()

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

Но это сделает n JOINs для n ингредиентов, и поэтому может легко стать невыполнимым для большого количества ingredients.

Вернуться на верх