Search code examples
pythondjangodjango-rest-frameworkdjango-serializer

exclude field from a nested serializer


to get the information of a user I use a serializer with nested serializers but I have a problem which is that I do not know how to exclude certain fields that are not necessary in this case the user's password, is there any way to exclude that field?

here is the code of the endpoint and the serializers

endpoint

@api_view(['GET'])
@has_permission_decorator('view_team_member')
def getTeamMembers(request, pk):
    try:
        token = decodeJWT(request)
        team_member = TeamMember.objects.filter(pk=pk, company_id=token['company_id'])
        print(team_member)
        serializer = TeamMemberSerializer(team_member, many=True)
        return Response({'data': serializer.data}, status=status.HTTP_200_OK)
    except TeamMember.DoesNotExist:
        return Response({'Error': 'Not Found'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

team member serializer

class TeamMemberSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    team = TeamSerializer(read_only=True)
    team_role = TeamRoleSerializer(read_only=True)
    company = CompanySerializer(read_only=True)

    class Meta:
        model = TeamMember
        fields = "__all__"
        read_only_fields = ['state', 'created_at', 'updated_at']
        required_fields = ['team', 'user', 'team_role']

user serializer

class UserSerializer(serializers.ModelSerializer):
    role = serializers.CharField(style={'input_type': 'text'}, write_only=True)
    password2 = serializers.CharField(style={'input_type': 'text'}, write_only=True)

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email', 'password', 'password2', 'company', 'role']
        extra_kwargs = {
            'username': {'required': True},
            'email': {'required': True},
            'first_name': {'required': True},
            'last_name': {'required': True},
            'role': {'required': True},
            'company': {'required': True},
            'password': {'required': True},
            'password2': {'required': True},
        }

    def save(self):
        password = self.validated_data['password']
        password2 = self.validated_data['password2']
        if password != password2:
            raise serializers.ValidationError({'password': 'Passwords must match'})

        if User.objects.filter(email=self.validated_data['email']).exists():
            raise serializers.ValidationError({'Email': 'Email already exists'})

        account = User(email=self.validated_data['email'],
                       company=self.validated_data['company'],
                       first_name=self.validated_data['first_name'],
                       last_name=self.validated_data['last_name'])
        account.set_password(password)
        account.save()
        user = User.objects.get(id=account.id)
        try:
            assign_role(user, self.validated_data['role'])
        except Exception as e:
            user.delete()
            raise serializers.ValidationError('invalid role')


response

{
    "data": [
        {
            "id": 1,
            "user": {
                "first_name": "anderson",
                "last_name": "worker",
                "email": "worker@gmail.com",
                "password": "pbkdf2_sha256$320000$CPoWGbsmw7xOKugwP4ygI7$4VpOy9LEDvDCWRHHn/GS6utuT9pYvtOGx+2aP7+IoI0=",
                "company": 1
            },
            "team": {
                "id": 1,
                "description": "frontend-team",
                "state": 1,
                "created_at": "2022-08-01T00:54:05.732842Z",
                "updated_at": null,
                "company": 1
            },
            "team_role": {
                "id": 1,
                "description": "backend-dev",
                "state": 1,
                "created_at": "2022-08-01T00:54:39.197085Z",
                "updated_at": null,
                "company": 1
            },
            "company": {
                "id": 1,
                "description": "infinity tech",
                "state": 1,
                "created_at": "2022-08-01T00:51:31.420658Z",
                "updated_at": null
            },
            "state": 1,
            "created_at": "2022-08-01T01:09:07.457835Z",
            "updated_at": null
        }
    ]
}

I want to remove the password field in the user object


Solution

  • You can create a new user serializer to use with TeamMemberSerializer.

    user serializer

    class UserSerializer2(serializers.ModelSerializer):
       class Meta:
          model = User
          fields = ['first_name', 'last_name', 'email', 'company']
    

    team member serializer

    class TeamMemberSerializer(serializers.ModelSerializer):
        user = UserSerializer2(read_only=True)
        team = TeamSerializer(read_only=True)
        team_role = TeamRoleSerializer(read_only=True)
        company = CompanySerializer(read_only=True)
    
        class Meta:
            model = TeamMember
            fields = "__all__"
            read_only_fields = ['state', 'created_at', 'updated_at']
            required_fields = ['team', 'user', 'team_role']