【问题标题】:Django - Nested serialization for Many to Many fieldsDjango - 多对多字段的嵌套序列化
【发布时间】:2018-01-20 12:50:20
【问题描述】:

我正在尝试创建 API,但序列化程序失败。 我无法弄清楚出了什么问题。

查看:

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)  

序列化器:

    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()],
            }
        } 

型号:

# 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')
        )

我得到的错误基本上是由于我对视图的错误请求而发生的,该请求失败了

serialzer.is_valid()

我不确定为什么我的 UserProfileSerialzer 无法正确序列化。

编辑 1

我现在面临以下错误:

    {
        "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."
            ]
        }

}

我相信这是因为我的序列化程序无法处理外键的嵌套关系和多对多关系。

编辑 2 - 我现在面临以下错误 -

 File "C:\code\django\wantedly\src\wantedly_webapp\serializers\UserSkillSerializer.py", line 49, in create
   user = UserProfileSerializer.create(UserProfileSerializer(),validated_data=user_data)

/api/v1/user/skills/ UNIQUE 约束处的 IntegrityError 失败: auth_user.username

【问题讨论】:

  • 你能发布完整的回溯吗?你知道ReturnDict 对象来自哪里吗?

标签: django django-rest-framework


【解决方案1】:

我相信您的问题不在serializer.is_valid() 行,而是在尝试呈现以下错误的那一行:

return Response({serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

这将失败,因为serializer.errorsReturnDict,而您正尝试使用{} 语法对其进行设置。改为使用:

return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【讨论】:

  • 请检查有问题的 Edit-1,我猜我的序列化程序不正确。你能否检查一下我的模型和序列化程序是否有相同的视图。从 dict 到 set 的转换就像一个魅力!
  • 您在“编辑 1”中提到的错误发生是因为您将 Django 对象作为数据传递给序列化程序,而序列化程序需要使用已定义模式的字典。 data = { user':request.data.get('user'),'skill_item':request.data.get('new_user_skill')} 是罪魁祸首。
  • 关于第二个错误,那是因为您的UserProfileSerializer 尝试创建一个新用户,而具有该用户名的用户已经存在。如果具有给定用户名的现有用户已经存在,您可能希望在您的视图中保护它并返回 400。顺便说一句,对于新问题,请打开新问题,否则很难对任何事情给出明确的答案。 :)
  • 请在此处查看更新的查询stackoverflow.com/questions/48365600/…
猜你喜欢
  • 2023-03-17
  • 2018-11-10
  • 1970-01-01
  • 2023-03-03
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
相关资源
最近更新 更多