简体   繁体   中英

Implement update method on a Nested Serializer in Django 1.11 and django _rest framework

I Implemented a class based view in the views.py though when I tried to update an employee I realized that it's like I'm trying to create new one yet I have the PUT method defined. I have have an issue updating the user details since user field is a Foreign key. 在此处输入图片说明

A user with that username already exists.
Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.

views.py

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

    def get_object(self, pk):
        try:
            return Employee.objects.get(pk=pk)
        except Employee.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        employee = self.get_object(pk)
        serializer = EmployeeSerializer(employee)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        employee = self.get_object(pk)
        serializer = EmployeeSerializer(employee, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py

class EmployeeSerializer(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', 'contract_type', 'company',
                  'tax_id_number', 'joining_date', 'job_title', 'skill', 'unit',
                  'department', 'identification_number', 'is_manager', 'active']

For writable nested serializer you need to define update or create methods:

class EmployeeSerializer(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', '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_data = validated_data.pop('user')
        if user_data:
            instance.user.first_name = user_data.get('first_name')
            instance.user.last_name = user_data.get('last_name')
            # update other user's fields here
            instance.user.save()
        employee = super(EmployeeSerializer, self).update(instance, validated_data)
        return employee

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM