E
E
EgorLee2021-09-16 00:56:20
Django
EgorLee, 2021-09-16 00:56:20

Am I doing the filter on a many to many search in django correctly?

Hi all! I have a question:

There are models:

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


And let's say there is an array of ingredient names: ['onion', 'pepper']

I want to find all the recipes that contain these ingredients, searching through Q does not give anything:
Recipe.objects.filter(Q(ingredients__name__icontains= 'лук') & Q(ingredients__name__icontains= 'перец'))


I do everything through this algorithm:
queryset = Recipe.objects.all()
for item in ingred:
                queryset = queryset.filter(ingredients__name__icontains="item")


This works, but what about the load on the database? How to make such a request optimally?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
L
Larisa .•º, 2021-09-16
@barolina

just pay attention to the Ingredient model, whether the GIN index is hung on the name field, if the database is POSTGRES
ps if you use icontains
, at this moment you probably have a typo

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

Recipe.objects.filter(ingredients_id__in = [1,2 ])

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question