根据字段值更改嵌套序列化器

时间:2020-03-10 14:28:57

标签: python django django-rest-framework

我当前正在尝试将以下序列化器实现为Profile序列化器。但我想为其添加一个条件。 配置文件序列化器

class UserProfileSerializer(serializers.ModelSerializer):
    role = serializers.ChoiceField(choices=(('Reader', u'Reader'), ('Author', u'Author'), ('Admin', u'Admin')))
    role_display = serializers.SerializerMethodField()
    class Meta:
        model = Profile
        fields = ('gender', 'birthday', 'icon', 'role', 'role_display')
        depth = 1

作者序列化器

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = '__all__'

阅读器序列化器

class ReaderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Reader
        fields = '__all__'

作者和读者表均与个人资料表具有一对一关系。 根据角色选项,我想显示一个特定的嵌套序列化器。

示例:

{
    "id": 19,
    "username": "maoji1",
    "password": "pbkdf2_sha256$180000$YhzDiqzJ4OyC$syzkwR5X3/H2p5NTB0JEK2zS5nvYu5ddHrTgy3cYU/E=",
    "email": "pbkdf2_sha256$180000$YhzDiqzJ4OyC$syzkwR5X3/H2p5NTB0JEK2zS5nvYu5ddHrTgy3cYU/E=",
    "profile": {
        "gender": "male",
        "birthday": "2020-03-10",
        "icon": null,
        "role": {
            is_vip:True,
            validate_date:...
      }
    }
}

阅读器型号

class Reader(models.Model):
    user = models.OneToOneField(Profile, on_delete=models.CASCADE, related_name='reader', verbose_name='user')
    is_user_vip = models.CharField(choices=(('normal', u'Normal'), ('vip', u'VIP')),
                                   default='normal',
                                   max_length=10,
                                   verbose_name=u'Vip status')
    vip_validate = models.DateField(verbose_name=u"Validate Until",
                                    auto_now_add=True, null=True,
                                    editable=False)

作者模型

class Author(models.Model):
    user = models.OneToOneField(Profile, on_delete=models.CASCADE, related_name='author')
    book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='Book', null=True)
    contract_number = models.IntegerField(verbose_name='Contact number', null=True, blank=True)

个人资料模型

class Profile(models.Model):
    role_choice = (
        ('Reader', u'Reader'),
        ('Author', u'Author'),
        ('Editor', u'Editor'),
        ('Admin', u'Admin')
    )
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', verbose_name='user')
    gender = models.CharField(choices=(("male", u"Male"), ("female", u"Female")),
                              default="Female",
                              max_length=150, verbose_name='Gender')
    birthday = models.DateField(null=True, blank=True, verbose_name="Birthday")
    icon = models.ImageField(upload_to="media/image/%Y/%m",
                             default=u"media/image/default.png",
                             max_length=1000,
                             verbose_name=u"User icon", null=True)
    role = models.CharField(choices=role_choice,
                            max_length=150,
                            default='Admin',
                            verbose_name='Role')

1 个答案:

答案 0 :(得分:0)

您可以使用SerializerMethodField并确定在其方法内必须使用哪个序列化器:

class UserSerializer(serializers.ModelSerializer):
    profile = serializers.MethodField()
    class Meta:
        model = Profile
        fields = ('id', 'username', 'password', 'email','profile')

    def get_profile(self,obj):
         return ProfileSerializer(obj.profile).data


class AuthorSerializer(serializers.ModelSerializer):
     class Meta:
         model = Author
         fields ='__all__' 


 class ReaderSerializer(serializers.ModelSerializer):
     class Meta:
         model = Reader
         fields ='__all__'  




class ProfileSerializer(serializers.ModelSerializer):
    role = serializers.MethodField()
    class Meta:
        model = Profile
        fields = ('gender', 'birthday', 'icon', 'role')

    def get_role(self,obj):
        if hasattr(obj, 'author')
            serializer = AuthorSerializer(obj.author)
            return serializer.data
        elif hasattr(self,'reader'):
            serializer = ReaderSerializer(obj.reader)
            return serializer.data
        return {} # if your profile doesn't have any relation with author or reader



 class UserSerializer(serializers.ModelSerializer):
    profile = serializers.MethodField()
    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'email','profile')

    def get_profile(self,obj):
         return ProfileSerializer(obj.profile).data