将可扩展字段添加到自相关模型上的序列化器

问题描述

我有一个用户详细信息”模型,该模型是“自相关”的,可以在两个用户之间建立关系。

型号

class AdvDetails(models.Model):
    user_id = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
    title = models.CharField(max_length=5,choices=[('Mr','Mr'),('Ms','Ms'),('Mrs','Mrs'),('Dr','Dr'),('NA','')],default='NA')
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    email_id = models.EmailField(null=True,blank=True,default=None)
    parent_profile = models.ForeignKey("self",null=True,blank=True)

视图集

class AdvDetailsViewSet(viewsets.ModelViewSet):
    serializer_class = AdvDetailsSerializer
    filter_backends = (filters.SearchFilter,DjangoFilterBackend,filters.OrderingFilter)
    filter_fields = ('email_id,'parent_profile')
    search_fields = (  '^first_name',)

    def get_queryset(self):
        return AdvDetails.objects.all()

序列化器

class AdvDetailsSerializer(serializers.ModelSerializer):

    class Meta:
        model = AdvDetails
        fields = '__all__'

这种结构有助于我以以下格式帮助获取数据

{
  "user_id": "055cbde6-10ea-4558-86fc-1b42624ce760","title": "Mr","first_name": "foo","last_name": "bar","email_id" : "foo@bar.com"
  "parent_profile":"6c429d4c-9fb4-42e5-9d7d-9fc782f81fb0"
}

我希望以如下方式修改序列化程序,以便我获得父配置文件email_id的数据,如下所示

{
  "user_id": "055cbde6-10ea-4558-86fc-1b42624ce760","email_id" : "foo@bar.com","parent_profile":"6c429d4c-9fb4-42e5-9d7d-9fc782f81fb0","parent_email_id" : "parent@email.com"
}

我们非常感谢您的帮助。我已经尝试过PrimaryKeyRelatedField,但是并不能解决我的问题。

解决方法

我制作了一个软件包,该软件包允许根据请求按需动态扩展字段: https://github.com/rsinger86/drf-flex-fields

针对您的情况:

class AdvDetailsSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = AdvDetails
        fields = ('user_id','title','first_name','last_name','email_id','parent_profile','parent_email_id' )
        expandable_fields = {'parent_profile': '<app_name>.AdvDetailsSerializer'}

<app_name>替换为定义序列化程序的Django应用的名称,以便可以延迟加载。

如果您想静态扩展字段,则可以将该字段定义为嵌套的序列化器:

class AdvDetailsSerializer(serializers.ModelSerializer):
    parent_profile = ProfileProfileSerializer()

    class Meta:
        model = AdvDetails
        fields = (
           'user_id','parent_email_id'
        )