Как получить конкретные объекты на основе совпадения полей 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
для получения всех ингридентов всех объектов данной модели (наименее рекомендуется).