我正在尝试解决这个问题:
用户可以为他的个人资料添加技能,而其他用户可以在他的个人资料中提升技能。
我已经实现了在系统中添加技能。 接下来,我正在尝试构建添加技能(已由管理员添加到系统中)以添加到用户配置文件中。
但在我的POST API中,我总是遇到以下错误
{
"user": {
"user": [
"This field is required."
]
}
}
身体输入:
{
"user":{
"username": "USERN",
"email": "diahu@gail.com",
"first_name": "",
"last_name": ""
},
"new_user_skill":
{
"id": 1,
"skill_name": "C"
}
}
我的观点:
elif request.method == 'POST':
data = { 'user':request.data.get('user'),'skill_item':request.data.get('new_user_skill')}
serializer = UserSkillSerializer(data=data)
print("-------------------> serializer ")
print(serializer)
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)
型号:
class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
extra_kwargs = {
'username': {
'validators': [],
}
}
class UserProfileSerializer(serializers.ModelSerializer):
user=UserModelSerializer()
class Meta:
model = UserProfile
fields = '__all__'
def create(self, validated_data):
user_serializer = UserModelSerializer.create(UserModelSerializer(),validated_data = validated_data)
user,created=UserProfile.objects.update_or_create(user=user_serializer)
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_item = SkillSerializer.create(SkillSerializer(),validated_data=skill_data)
user_skill, created = UserSkill.objects.update_or_create(user=user,skill_item=skill_item)
return user_skill
Serializer:
class SkillSerializer(serializers.ModelSerializer):
class Meta:
model = Skill
fields = '__all__'
extra_kwargs = {
'skill_name': {
'validators': [],
}
}
class UserModelSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
extra_kwargs = {
'username': {
'validators': [],
}
}
class UserProfileSerializer(serializers.ModelSerializer):
user=UserModelSerializer()
class Meta:
model = UserProfile
fields = '__all__'
def create(self, validated_data):
user_serializer = UserModelSerializer.create(UserModelSerializer(),validated_data = validated_data)
user,created=UserProfile.objects.update_or_create(user=user_serializer)
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_item = SkillSerializer.create(SkillSerializer(),validated_data=skill_data)
user_skill, created = UserSkill.objects.update_or_create(user=user,skill_item=skill_item)
return user_skill
我已删除验证器(不确定这是否正确)
修改1
我根据答案编辑了很多代码(我研究并实现了反向关系),面对一个Not Null约束,即使我有 null = True
我的更新代码:
Serializer:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email','user_profile')
class UserSkillSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(read_only=True)
skill_item = serializers.PrimaryKeyRelatedField(read_only=True)
class Meta:
model = UserSkill
fields= ('user', 'skill_item')
观点:
elif request.method =='POST':
current_user = User.objects.get(pk=request.data.get('user')) # get the user key
user_profile_id = current_user.user_profile.pk # get the user profile from reverse relation in model
data = { 'user':user_profile_id,'skill_item':request.data.get('skill_id')}
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)
型号:
# 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,null=True)
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'),null=True
)
#create user profile signal handler
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
错误:
return func(*args, **kwargs) File "C:\code\django\wantedly\src\wantedly_webapp\views\AllViews.py", line
61,在user_skill_collection中 serializer.save()
/ api / v1 / user / skills / NOT NULL约束中的IntegrityError失败: wantedly_webapp_userskill.skill_item_id
答案 0 :(得分:1)
生成此错误是因为UserProfileSerializer
具有需要整个用户定义的user
字段。一般来说,我相信你会混合概念"用户档案" /"用户"在您的序列化程序中,这会造成混淆。
创建User
及其关联的UserProfile
和Skill
后,将Skill
添加到UserProfile
的方法是选择它们按主键:
class UserSkillSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField()
skill_item = serializers.PrimaryKeyRelatedField()
class Meta:
model = UserSkill
fields= ('user', 'skill_item')
将Skill
分配给UserProfile
的POST数据将为:
{
"user": 3, # PK of the UserProfile, not the User!
"skill_item": 42 # PK of the SkillItem you want to assign
}