Как получить конкретные объекты на основе совпадения полей ManyToMany

Я делаю приложение для кулинарной книги, которое помогает пользователям найти блюда, которые они могут сделать с помощью своих ингридиентов. Я использую Django RestFramework, и мне нужно вернуть список доступных блюд, которые может сделать пользователь, но я не знаю, как сделать поиск по ингридиентам

Мой models.py:

#models.py
class Meal(models.Model):
    name = models.CharField(max_length=250)
    description = models.TextField(blank=True, null=True)
    recipe = models.TextField()
    is_published = models.BooleanField(default=False)
    category = ForeignKey('Category', on_delete=models.CASCADE, null=True)
    user = ForeignKey(User, verbose_name='User', on_delete= models.CASCADE)
    difficulty = ForeignKey('Difficulty', on_delete=models.PROTECT, null=True)
    ingridients = models.ManyToManyField('Ingridient')

class Ingridient(models.Model):
    name = models.CharField(max_length=100, db_index=True)
    ico = models.ImageField(upload_to="photos/%Y/%m/%d/", blank=True, null=True)
    category = ForeignKey('CategoryIngridients', on_delete=models.CASCADE, null=True)

    def __str__(self):
        return self.name

class CookBookUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    ingridients = models.ManyToManyField('Ingridient')

serializer.py

class MealSerializer(serializers.ModelSerializer):
    class Meta:
        model = Meal
        fields = "__all__"

views.py

class CraftWithUsersIngridientsListAPIView(generics.ListAPIView):
    serializer_class = MealSerializer

    def get_queryset(self):
       return Meal.objects.filter(ingridients=CookBookUser.objects.filter(user_id = self.request.user.id).ingridients)

CraftWithUsersIngridientsListAPIView не работает и я получаю AttributeError 'QuerySet' object has no attribute 'ingridients', может кто-нибудь помочь исправить это?

Я пробовал собирать разные сериализаторы, но это не помогает

class CraftWithUsersIngridientsListAPIView(generics.ListAPIView):
    serializer_class = MealSerializer

    def get_queryset(self):
        user_ingredients = CookBookUser.objects.get(user=self.request.user).ingredients.all()
        return Meal.objects.filter(ingredients__in=user_ingredients)

Таким образом, сначала вы получаете экземпляр CookBookUser для текущего пользователя, затем получаете все его ингредиенты и, наконец, фильтруете объекты Meal, содержащие эти ингредиенты. Поиск запроса __in используется для проверки наличия ингредиентов блюда в ингредиентах пользователя.

В функции get_queryset(),

Meal.objects.filter(ingridients=CookBookUser.objects.filter(user_id = self.request.user.id).ingridients)

CookBookUser.objects.filter(user_id = self.request.user.id) вернет кверисет CookBookUser Model, а у кверисета нет атрибутов.

Вместо этого попробуйте следующее, CookBookUser.objects.filter(user_id = self.request.user.id)[0].ingridients для получения ингредиентов первого объекта.

Или вот это, CookBookUser.objects.filter(user_id = self.request.user.id).all().value_list('ingridients', flat=True) для получения ингридентов всех объектов.

Также можно использовать for loop для получения всех ингридентов всех объектов данной модели (наименее рекомендуется).

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