DRF: Создание миксина с использованием различных сериализаторов и объектов

У меня есть два класса APIView с почти одинаковым поведением (и кодом). Отличаются только сериализаторами и объектами моделей (Favorite & FavoriteSerializer для первого класса и PurchaseList и PurchaseListSerializer для второго). Насколько я понимаю, это идеальный случай использования миксина, согласно документации DRF ([DRF: Creating custom mixins] 1https://www.django-rest-framework.org/api-guide/generic-views/).

К сожалению, я не могу понять, как определить mixin без определения serializer & obj в нем.

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
        )

Вы можете создать свой собственный миксин следующим образом:

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

Или использовать GenericApiView с миксинами bulti-in

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

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