Search code examples
djangodjango-rest-frameworkdjango-filter

How can I add an extra field in the response to understand which item triggered the search result


I have two simple recipe and ingredient models.

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')

I have added a filter for recipe search where I can add ingredient ids as parameter. It returns the recipes which have those ingredients. The filter is as follows,

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 = []

The url is something like this

/recipes/?ingredient_have=id1,id2

The response is something like

{
    "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"
                }
            ]
        }
    ]
}

Currently, the url is giving me the list of recipes if any of the ingredients' id (of any recipe) is id1 or id2. Now I would like to mark that particular ingredient (id1/id2) so that the frontend understands for which ingredient the recipe is in the response. I would like to add an extra field (in Ingredient) so that I can understand in the frontend which ingredient has triggered the recipe to be in the search result such as,

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

The "highlight" field is imaginary here and that's what I would like to achieve.

I hope I made the problem clear. Could you please give me some suggestion/solution?

Thanks in advance.


Solution

  • I solve this problem in serializer,

    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
    

    Thats how I can get the query parameters and highlight the ingredient to indicate why this recipe is in the search result.