Задать вопрос
@EgorLee

Правильно ли я делаю фильтр по поиску many to many в django?

Привет всем! У меня такой вопрос:

Есть модели:

class Ingredient(models.Model):
    name = models.CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name


class Tag(models.Model):
    name = models.CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name


class Recipe(models.Model):
    title = models.CharField(max_length=255)
    photo = models.ImageField(upload_to="recipe_photo/", blank=True)
    lvl_skill = models.CharField(max_length=50)
    country_kitchen = models.CharField(max_length=255)
    category = models.CharField(max_length=255)
    step_cooking = models.TextField()
    tags = models.ManyToManyField(Tag)
    ingredients = models.ManyToManyField(Ingredient, through='Ingredient_count')

    def __str__(self):
        return self.title

    class Meta:
        ordering = ('title',)

class Ingredient_count(models.Model):
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, null=True)
    ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE, null=True)
    count = models.CharField(max_length=255)

    def __str__(self):
        # return self.ingredient.name
        return self.count


И допустим есть массив названий ингредиентов: ['лук', 'перец']

Я хочу найти все рецепты где есть данные ингредиенты, поиск через Q, ничего не дает:
Recipe.objects.filter(Q(ingredients__name__icontains= 'лук') & Q(ingredients__name__icontains= 'перец'))


Я делаю все через такой алгоритм:
queryset = Recipe.objects.all()
for item in ingred:
                queryset = queryset.filter(ingredients__name__icontains="item")


Это работает, но как на счет нагрузки на БД? Как составить такой запрос оптимально?
  • Вопрос задан
  • 112 просмотров
Подписаться 2 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
@barolina
turn coffee into code
только обратить внимание на модель Ingredient, повешен ли индекс GIN на поле name, если бд POSTGRES

p.s. если вы используете icontains

вот в этом моменте видимо у вас опечатка

for item in ingred:
                queryset = queryset.filter(ingredients__name__icontains="item")


Recipe.objects.filter(ingredients_id__in = [1,2 ])
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы