Skip to content

Commit

Permalink
Implement recipe filter feature
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlo-myskov committed Nov 13, 2023
1 parent cca0bb9 commit 523a44e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ REST API with Python, Django REST Framework and Docker using Test Driven Develop
* Delete ingredient
- Recipe Image API
* Upload image to recipe
- Filter recipes by tags and ingredients
- How to use:
- `<host>/api/recipes/?tags=<comma_separated_tag_ids>`
- `<host>/api/recipes/?ingredients=<comma_separated_ingredient_ids>`


## Documentation
The API documentation is created using [drf-spectacular](https://drf-spectacular.readthedocs.io/en/latest/).
Expand Down
41 changes: 39 additions & 2 deletions app/recipe/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
"""
Views for the recipe APIs.
"""
from drf_spectacular.utils import extend_schema, extend_schema_view
from drf_spectacular.utils import (
extend_schema_view,
extend_schema,
OpenApiParameter,
OpenApiTypes,
)

from rest_framework import viewsets, mixins, status
from rest_framework.decorators import action
Expand All @@ -18,6 +23,18 @@
list=extend_schema(
summary='Retrieve a list of recipes',
description='Retrieve a list of recipes for the authenticated user.',
parameters=[
OpenApiParameter(
'tags',
OpenApiTypes.STR,
description='Comma separated list of tags IDs to filter',
),
OpenApiParameter(
'ingredients',
OpenApiTypes.STR,
description='Comma separated list of ingredients IDs to filter'
),
]
),
create=extend_schema(
summary='Create a new recipe',
Expand Down Expand Up @@ -47,9 +64,29 @@ class RecipeViewSet(viewsets.ModelViewSet):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]

def _params_to_ints(self, qs):
"""Convert a list of strings to integers."""
return [int(str_id) for str_id in qs.split(',')]

def get_queryset(self):
"""Retrieve recipes for authenticated user."""
return self.queryset.filter(user=self.request.user).order_by('-id')
# retrieve query params provided as string of comma separated values
tags = self.request.query_params.get('tags')
ingredients = self.request.query_params.get('ingredients')
queryset = self.queryset

# filter queryset based on query params
if tags:
tag_ids = self._params_to_ints(tags)
queryset = queryset.filter(tags__id__in=tag_ids)
if ingredients:
ingredient_ids = self._params_to_ints(ingredients)
queryset = queryset.filter(ingredients__id__in=ingredient_ids)

# return filtered queryset for authenticated user
return queryset.filter(
user=self.request.user
).order_by('-id').distinct()

def get_serializer_class(self):
"""Return the serializer class for request."""
Expand Down

0 comments on commit 523a44e

Please sign in to comment.