Как я могу добавить дополнительное поле в ответ, чтобы понять, какой элемент вызвал результат поиска

У меня есть простой рецепт и модели ингредиентов.

class Ingredient(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)

class Recipe(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    ingredients = models.ManyToManyField(Ingredient, related_name='recipe_ingredients')

Я добавил фильтр для поиска рецептов, когда я могу добавить идентификаторы ингредиентов в качестве параметра. Он возвращает рецепты, в которых есть эти ингредиенты. Фильтр выглядит следующим образом,

class RecipeFilter(django_filters.FilterSet):
    ingredient_have = django_filters.CharFilter(method='filter_ingredient_have')

    def filter_ingredient_have(self, queryset, name, value):
        if value:
            ids = value.split(',')
            return queryset.filter(Q(ingredients__id__in=ids))
        return queryset


    class Meta:
        model = Recipe
        fields = []

Урл выглядит примерно так

/recipes/?ingredient_have=id1,id2

Ответ будет примерно таким

{
    "items": [
        {
            "id": "13261f0d-408d-4a51-9cc2-cb69ee72fe24",
            "name": "Curry",
            "ingredients": [
                {
                    "id": "08089ff8-03fb-4946-be61-659d799ca996",
                    "name": "oil"
                },
                {
                    "id": "dc9cb6f2-1810-48eb-b7a7-52a4bd9fdccb",
                    "name": "water"
                }
            ]
        }
    ]
}

Я хотел бы добавить дополнительное поле (в Ingredient), чтобы я мог понять во фронтенде, какой ингредиент вызвал появление рецепта в результатах поиска, например,

{
    "id": "08089ff8-03fb-4946-be61-659d799ca996",
    "name": "oil",
    "highlight": false/true
}

Надеюсь, я ясно изложил суть проблемы. Не могли бы вы дать мне какое-нибудь предложение/решение?

Заранее спасибо.

Вы можете добавить еще одно поле в модель "Ингредиенты", просто изменив класс Ingredients(). В вашем случае вам понадобится BooleanField.

class Ingredient(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    highlight = models.BooleanField(default=False)

Не забудьте использовать команду migrate, чтобы применить эти изменения к базе данных.

Кроме того, добавление такого поля, как default=False, предотвратит любые проблемы для объектов, уже добавленных в вашу базу данных. Вам не нужно будет вручную добавлять значение ingredients для каждого из них, потому что им будет автоматически присвоено значение False.

Я решил эту проблему в сериализаторе,

class IngredientSerializer(BaseSerializer):
    isHighlight = serializers.SerializerMethodField()
    def get_isHighlight(self, obj):
        ids = []
        if 'request' in self.context and 'ingredient_have' in self.context['request'].query_params:
            ingredient_have = self.context['request'].query_params['ingredient_have']
            if ingredient_have:
                ids.extend(ingredient_have.split(','))
        if str(obj.id) in ids:
            return True
        return False

Так я могу получить параметры запроса и выделить ингредиент, чтобы указать, почему этот рецепт находится в результатах поиска.

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