DRF - 将不同的模型序列化为一个

时间:2016-10-13 16:56:50

标签: django django-rest-framework

我有几个将用户作为外键的模型。例如,我有模型Profile,模型profilePic和模型userQuestions - 在所有模型中用户都是外键。

有没有办法可以在一个json响应中获得与给定用户对应的profileprofilePicuserQuestions

我的models.py正在关注

class Profile(models.Model):
   user = models.OneToOneField(User, on_delete=models.CASCADE)
   gender = models.CharField(max_length=2)
   name = models.CharField(max_length=200)
   birthday = models.DateField(auto_now=False, auto_now_add=False)
   weight = models.IntegerField(default=0)
   heigth = models.IntegerField(default=0)
   sign = models.CharField(max_length=200, choices=SIGNS_CHOICES, default='E')
   orientation = models.CharField(max_length=200, choices=ORIENTATION_CHOICES, default='E')
   bodytype = models.CharField(max_length=200, choices=BODYTYPE_CHOICES, default='E')
   education = models.CharField(max_length=200, choices=EDUCATION_CHOICES, default='E')
   religion = models.CharField(max_length=200, choices=RELIGION_CHOICES, default='E')
   smoking = models.CharField(max_length=200, choices=SMOKING_CHOICES, default='E')
   alcohol = models.CharField(max_length=200, choices=ALCOHOL_CHOICES, default='E')
   kids = models.CharField(max_length=200, choices=KIDS_CHOICES, default='E')
   pets = models.CharField(max_length=200, choices=KIDS_CHOICES, default='E')
   location = models.CharField(max_length=100)
   latitude = models.FloatField()
   longtitude = models.FloatField()

class ProfileFields(models.Model):
   user = models.ForeignKey(User, on_delete=models.CASCADE)
   title = models.CharField(max_length=200)
   text = models.TextField()
   order = models.IntegerField(default=0)

class ProfilePic(models.Model):
   user = models.OneToOneField(User, on_delete=models.CASCADE)
   profilePic = models.ImageField(upload_to='Images/', default='Images/None/No-img.jpg')

class Pics(models.Model):
   user = models.ForeignKey(User, on_delete=models.CASCADE)
   pic = models.ImageField(upload_to='Images/', default='Images/None/No-img.jpg')

UPD

尝试添加

def to_representation(self, data):
    profile_info = {kv: data[kv] for kv in data if kv in list(ProfileSerializer.Meta.fields)}
    profile_pic_info = {kv: data[kv] for kv in data if kv in list(ProfilePicSerializer.Meta.fields)}

    return super(DeviceInfoSerializer, self).to_representation({
    'profile': profile_info,
    'profile_pic': profile_pic_info,
    })

但现在它说对象'用户'不可迭代

2 个答案:

答案 0 :(得分:0)

您可以将nested serializers添加到UserSerializer。这样的事情。

class ProfileSerializer(serializers.ModelSerializer)
    class Meta:
        model = Profile
        fields = '__all__'

class ProfilePicSerializer(serializers.ModelSerializer)
    class Meta:
        model = ProfilePic
        fields = '__all__'

class UserQuestionsSerializer(serializers.ModelSerializer)
    class Meta:
        model = UserQuestions
        fields = '__all__'

class UserSerializer(serializers.ModelSerializer)
    profile = ProfileSerializer(many=False)
    profilepic = ProfilePicSerializer(many=False)
    user_questions = UserQuestionsSerializer(mane=True)

    class Meta:
        model = User
        fields = '__all__'

答案 1 :(得分:0)

在一个月前遇到同样的问题并且在SO上找不到好的答案。 Sardorbek的答案是完全正确的,如果您不关心json响应是否持平。该代码创建的JSON类似于:

{ 
  "profile": {"name": ..., "gender": ..., "birthday": ...,},
  "profile_pic": {"profilePic": ...., },
  "user_questions": [{...}, {...}, ...]
  User model attributes go here...
}

但是如果你想要它是平的,比如:

{
    "name": ...,
    "gender": ...,
    "birthday": ...,
    ....
    "profilePic": ...,
    "user_questions": [{...}, {...}, ...],
    User model attributes go here...
}

你需要一点点破解。以这种方式覆盖to_internal_value课程中的UserSerializer

def to_internal_value(self, data):
    profile_info = {kv: data[kv] for kv in data if kv in list(ProfileSerializer.Meta.fields)}
    profile_pic_info = {kv: data[kv] for kv in data if kv in list(ProfilePicSerializer.Meta.fields)}

    return super(DeviceInfoSerializer, self).to_internal_value({
        'profile': profile_info,
        'profile_pic': profile_pic_info,
    })

您也可能需要覆盖to_representation,但也有类似想法。