Django Rest Framework - 嵌套用户中的用户资料

3

我正在使用Django的Rest框架来展示用户信息。每个用户都有一些联系人,这些联系人保存在UserProfile中(用户资料使用一对一的关系)。可直接在用户模型中访问联系人(user.contacts)。


我想显示一个用户所有联系人的名称(和URL)。我编写了以下序列化程序:

class ContactsUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = get_user_model()
        fields = ("username", "email")


class ContactsSerializer(serializers.ModelSerializer):
    # user = ContactsUserSerializer(many=True) # raises TypeError: 'User' object is not iterable
    class Meta:
        model = UserProfile
        fields = ("user",)


class UserSerializer(serializers.HyperlinkedModelSerializer):
    contacts = ContactsSerializer(many=True)

    class Meta:
        model = get_user_model()
        fields = ("url", "username", "email", "contacts")

which return

{
  "url": "http:\/\/localhost:8080\/users\/1\/",
  "username": "test1",
  "email": "",
  "contacts": [
    {
      "user": 2
    },
    {
      "user": 1
    }
  ]
}

但我希望它是:

{
  "url": "http:\/\/localhost:8080\/users\/1\/",
  "username": "test1",
  "email": "",
  "contacts": [
    {
      "url": "http://link_to_user",
      "username": "foo"
    },
    {
      "url": "http://link_to_user",
      "username": "bar"
    }
  ]
}

我该如何实现这一点?我已经尝试为联系人用户添加另一个序列化器,但这会引发类型错误:“User”对象不可迭代,并且JSON结构看起来有些尴尬:{contacts:[user:{“username”:...},]},如果API的用户不熟悉Django的用户配置文件,则可能会让他感到困惑。
1个回答

7

为了让url字段自动添加,您的ContactsSerializer需要成为一个HyperlikedModelSerializer。由于您需要将url字段指向不同模型,因此实际上需要使用HyperlinkedRelatedField,并将其作为序列化程序上的自定义字段添加。

class ContactsSerializer(serializers.ModelSerializer):
    url = serializers.HyperlinkedRelatedField(view_name="user-detail", source="user")
    username = serializers.CharField(source="user.username")

    class Meta:
        model = UserProfile
        fields = ("url", "username", )

您可以使用source参数来指定模型中与显示不同的字段。在此情况下,我们正在使用配置文件上的user关系中的字段。
如果您正在使用路由器或按照教程操作,则user-detail将是默认视图名称。您可能需要调整此名称以匹配您的详细视图名称。

功能完美,但应该使用HyperlinkedRelatedField(或HyperlinkedIdentityField)而不是HyperlinkedModelSerializer - Matt3o12

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接