Reputation: 2742
I am trying to create an API but the serializer is failing . I am not able to figure out what has gone wrong .
View :
elif request.method == 'POST':
data = { 'user':request.data.get('user'),'skill_item':request.data.get('new_user_skill')}
serializer = UserSkillSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Serializer :
class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
extra_kwargs = {
'username': {
'validators': [UnicodeUsernameValidator()],
}
}
class UserProfileSerializer(serializers.ModelSerializer):
skill_item =SkillSerializer(read_only=True,many=True)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email','skill_item')
extra_kwargs = {
'username': {
'validators': [UnicodeUsernameValidator()],
}
}
def create(self, validated_data):
user = UserModelSerializer.create(UserModelSerializer(),username=validated_data.get('username'))
user.save()
UserProfile.objects.create(user=user, user_skills=skill_item)
return user
class UserSkillSerializer(serializers.ModelSerializer):
user = UserProfileSerializer(required=True)
skill_item = SkillSerializer(required=True)
class Meta:
model = UserSkill
fields= '__all__'
def create (Self,validated_data):
user_data = validated_data.pop('user')
user = UserProfileSerializer.create(UserProfileSerializer(),validated_data=user_data)
skill_data = validated_data.pop('skill_item')
skill = SkillSerializer.create(SkillSerializer(),validated_data=skill_data)
user_skill, created = UserSkill.objects.update_or_create(user=user,skill_item=skill_item)
return user_skill
class SkillSerializer(serializers.ModelSerializer):
class Meta:
model = Skill
fields = '__all__'
extra_kwargs = {
'skill_name': {
'validators': [UnicodeUsernameValidator()],
}
}
Model :
# This class will more or less map to a table in the database and defines skills at the application level
class Skill (models.Model):
# this defines a required name that cannot be more than 100 characters.
skill_name = models.CharField(max_length=100,unique=True)
class Meta:
app_label = "wantedly_webapp"
# This class will more or less map to a table in the database and defines the many to many relationship between user-skill, this is our intermediate model
class UserSkill(models.Model):
""" A Model for representing skill in user profile """
unique_together = (('user', 'skill_item'),)
user = models.ForeignKey('UserProfile',on_delete=models.CASCADE,related_name='current_user_skills')
skill_item = models.ForeignKey(Skill,on_delete=models.CASCADE)
def __str__(self):
"""Return a human readable representation of the model instance."""
return "{}".format(self.skill_item.skill_name)
# this class adds a Many to Many field in existing django-rest auth UserProfile class for user and his/her skills
class UserProfile(models.Model):
user = models.OneToOneField('auth.User',unique=True,on_delete=models.CASCADE,related_name='user_profile')
user_skills = models.ManyToManyField(
Skill,
through='UserSkill',
through_fields=('user','skill_item')
)
The error which I am getting is basically happening because of my bad request to the view , which failes on
serialzer.is_valid()
I am not sure why my UserProfileSerialzer is not able to serialze correctly .
Edit 1
I am facing following errors now :
{
"user": {
"non_field_errors": [
"Invalid data. Expected a dictionary, but got User."
]
},
"skill_item": {
"non_field_errors": [
"Invalid data. Expected a dictionary, but got Skill."
]
}
}
I believe this is happening because my Serializer are not able to handle the Nested relations of foreign key and many to many relations .
Edit 2 - I am facing following errors now -
File "C:\code\django\wantedly\src\wantedly_webapp\serializers\UserSkillSerializer.py", line 49, in create
user = UserProfileSerializer.create(UserProfileSerializer(),validated_data=user_data)
IntegrityError at /api/v1/user/skills/ UNIQUE constraint failed: auth_user.username
Upvotes: 0
Views: 1023
Reputation: 7185
I believe your problem is not on the serializer.is_valid()
line, but on the one trying to render errors below:
return Response({serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
This will fail because serializer.errors
is a ReturnDict
and you are trying to make a set of it using the {}
syntax. Use instead:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Upvotes: 1