0

I want to show an error when trying to create a profile but user already has one

in my views.py

class ProfileViewSet(viewsets.ModelViewSet):
    serializer_class = ProfileSerializer

    def get_queryset(self):
        queryset = Profile.objects.filter(owner=self.request.user)
        return queryset

    def get_permissions(self):
        permission_classes = []
        if self.action == 'create':
            permission_classes = [IsAuthenticated]
        elif self.action == 'retrieve' or self.action == 'update' or self.action == 'partial_update':
            permission_classes = [IsOwner]
        elif self.action == 'list':
            permission_classes = [IsAuthenticated]
        elif self.action == 'destroy':
            permission_classes = [IsAdminUser]
        return [permission() for permission in permission_classes]

    def perform_create(self, serializer):
        profile = Profile.objects.filter(owner=self.request.user)
        if not profile.exists():
            serializer.save(owner=self.request.user)
        else:
            return Response(data={'detail': 'This user already has a profile'}, status=status.HTTP_400_BAD_REQUEST)

when I create a profile on a user who already has one I don't get to show the error

Akond
  • 9
  • 4

1 Answers1

1

perform_create is not correct place to do such checks. It does not return anything.

You can do your check in the create method of viewset:

class ProfileViewSet(viewsets.ModelViewSet):

    ...

    def create(self, request, *args, **kwargs):
        if Profile.objects.filter(owner=self.request.user).exists():
            return Response(data={'detail': 'This user already has a profile'}, status=status.HTTP_400_BAD_REQUEST)

        return super().create(request,*args,**kwargs)

Or you can leave your viewset clean and simple and perform the check in your serializer's validate method. You just need to pass in the user instance when creating serializer. You can do so using serializer's context. Context docs.

Enthusiast Martin
  • 3,041
  • 2
  • 12
  • 20