5

I am using django rest framework I am trying to implement an update method to a nested serializer. How do I implement an update method to nested serializer correctly?

I'm trying to update an existing employee but I get the following response:

{
    "user": {
        "username": [
            "A user with that username already exists."
        ]
    }
}

I have implemented an update method on the serializers just to update the user fields.

class EmployeeUpdateSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    contract_type = ContractSerializer(read_only=True)
    company = CompanySerializer(read_only=True)
    job_title = JobSerializer(read_only=True)
    department = DepartmentSerializer(read_only=True)
    skill = SkillSerializer(read_only=True)
    unit = UnitSerializer(read_only=True)

    class Meta:
        model = Employee
        fields = ['id', 'user', 'hr_number', 'nssf_no', 'nhif_no', 'induction_date',
                  'induction_date', 'contract_type', 'company',
                  'tax_id_number', 'joining_date', 'job_title', 'skill', 'unit',
                  'department', 'identification_number', 'is_manager', 'active']

    def update(self, instance, validated_data):
        user = validated_data.get('user')
        instance.user.first_name = user.get('first_name')
        instance.user.save()

        return instance

Then in the views I have implemented the following:

class EmployeeDetailView(APIView):
    permission_classes = [AllowAny]
    # queryset = Employee.objects.all()
    serializer_class = EmployeeUpdateSerializer
    """
    Retrieve, update or delete a employee instance.
    """

    def get(self, request, pk, format=None):
        try:
            employee = Employee.objects.get(pk=pk)
        except Employee.DoesNotExist:
            raise Http404
        serializer = EmployeeUpdateSerializer(employee)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def put(self, request, pk, format=None):
        try:
            employee = Employee.objects.get(pk=pk)
            serializer = EmployeeUpdateSerializer(
                employee, data=request.data)
        except Employee.DoesNotExist:
            raise Http404
        # serializer = EmployeeUpdateSerializer(data=request.data)
        if serializer.is_valid():
            print(serializer.data)
            serializer.update()
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        return Response(serializer.data, status=status.HTTP_200_OK)
4
  • 1
    Have you tried patch instead of put ? Because put just updates everything Commented May 16, 2018 at 8:00
  • I have tried patch but I get the same results. Commented May 16, 2018 at 9:01
  • Did you tried creating a validation ? For instance you could validate user's username on update, if username is different then update it, if the same then pass ? Commented May 16, 2018 at 9:56
  • i think that will work Commented May 16, 2018 at 10:58

1 Answer 1

1

The UniqueValidator on your username field in UserSerializer is causing this issue, it's running a validation against the queryset to check if the username already exists.

You can remove this validation in your UserSerializer by adding the following to the Meta class:

        extra_kwargs = {
        'username': {
            'validators': [],
        },
    }

This is a quick and dirty fix as it will cause integrity issues with your DB if you try and save 2 instances with the same username.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.