DRF:使用不同的序列化器和对象创建 mixin

DRF: Creating mixin using different serializers & objects

我有两个具有几乎相似行为(和代码)的 APIView classes。不同的只是序列化器和模型对象(第一个 class 的 Favorite 和 FavoriteSerializer 以及第二个的 PurchaseList 和 PurchaseListSerializer)。据我所知,根据 DRF 文档([DRF:创建自定义 mixins] 1https://www.django-rest-framework.org/api-guide/generic-views/),它是 mixin 的完美用例。

不幸的是,我正在为如何在其中定义没有序列化程序和 obj 的情况下定义 mixin 而苦恼。

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 与内置 mixins 一起使用

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