1

I have two APIView classes with almost similar behaviour (and code). Different are only serializers and models object (Favorite & FavoriteSerializer for first class and PurchaseList and PurchaseListSerializer for second). As far as I understand it is a perfect usecase for mixin, according to DRF docs ([DRF: Creating custom mixins] 1https://www.django-rest-framework.org/api-guide/generic-views/).

Unfortunately, I'm struggling with how to define mixin without the definition of serializer & obj in it.

class FavoriteViewSet(APIView):
    def get(self, request, recipe_id):
        user = request.user.id
        data = {"user": user, "recipe": recipe_id}
        serializer = FavoriteSerializer(
            data=data,
            context={"request": request},
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status.HTTP_201_CREATED)

    def delete(self, request, recipe_id):
        user = request.user
        favorite_recipe = get_object_or_404(
            Favorite, user=user, recipe__id=recipe_id
        )
        favorite_recipe.delete()
        return Response(
            "Рецепт удален из избранного", status.HTTP_204_NO_CONTENT
        )


class PurchaseListView(APIView):
    def get(self, request, recipe_id):
        user = request.user.id
        data = {"user": user, "recipe": recipe_id}
        serializer = PurchaseListSerializer(
            data=data, context={"request": request}
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status.HTTP_201_CREATED)

    def delete(self, request, recipe_id):
        user = request.user
        purchase_list_recipe = get_object_or_404(
            PurchaseList, user=user, recipe__id=recipe_id
        )
        purchase_list_recipe.delete()
        return Response(
            "Рецепт удален из списка покупок", status.HTTP_204_NO_CONTENT
        )

1 Answer 1

1

You can create your own mixin like this:

class CustomMixin:
    serializer_class = None
    model_class = None

    def get(self, request, recipe_id):
        user = request.user.id
        data = {"user": user, "recipe": recipe_id}
        serializer = self.serializer_class(
            data=data,
            context={"request": request},
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status.HTTP_201_CREATED)

    def delete(self, request, recipe_id):
        user = request.user
        obj = get_object_or_404(
            self.model_class, user=user, recipe__id=recipe_id
        )
        obj.delete()
        return Response(
            "Рецепт удален из избранного", status.HTTP_204_NO_CONTENT
        )


class FavoriteViewSet(CustomMixin, APIView):
    serializer_class = FavoriteSerializer
    model_class = Favorite


class PurchaseListView(CustomMixin, APIView):
    serializer_class = PurchaseListSerializer
    model_class = PurchaseList

Or use the GenericApiView with the bulti-in mixins

https://www.django-rest-framework.org/api-guide/generic-views/#genericapiview

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! Exactly what I was looking for

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.