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