序列化器:HyperlinkedModelSerializer

官方文档原文

HyperlinkedModelSerializer 类与 ModelSerializer 类相似,只不过它使用超链接来表示关系而不是主键。

默认情况下,序列化器将包含一个 url 字段而不是主键字段。
url 字段将使用 HyperlinkedIdentityField 序列化器字段来表示,并且模型上的任何关系都将使用 HyperlinkedRelatedField 序列化器字段来表示。




我们沿用上一篇的 User 和 Profile 对象关系模型来作为例子:

# models.py

from django.db import models

class Profile(models.Model):
    city = models.CharField(max_length=50)
    owner = models.OneToOneField('auth.User', related_name='user_profile')

更新我们的序列化器:

# serializers.py

from rest_framework import serializers
from myApp.models import Profile
from django.contrib.auth.models import User


class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Profile
        # HyperlinkedModelSerializer 会自动生成一个 url 字段来表示超链接
        # 我们希望 API 中包括这个字段,所以这里我们在 fields 加上
        fields = ('url', 'city', 'owner')

        # 我们可以在 extra_kwargs 设置中的 view_name 和 lookup_field
        # 来正确配置我们的 URL
        # view_name 和 urls.py 中的 name 参数相对应,表示使用哪个 url
        # lookup_field 表示用哪个字段来作为 url 的唯一识别标记
        # 本例中每个 Profile 的 url 是通过 id 来区分的,所以该字段用 id
        extra_kwargs = {
            'url': {'view_name': 'profile-detail', 'lookup_field': 'id'},
            'owner': {'lookup_field': 'id'}
        }


class UserSerializer(serializers.HyperlinkedModelSerializer):
    user_profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'user_profile')

        extra_kwargs = {
            'url': {'view_name': 'user-detail', 'lookup_field': 'id'},
        }

编写 API 视图函数:

# views.py 

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response

from myApp.serializers import ProfileSerializer, UserSerializer
from django.contrib.auth.models import User
from myApp.models import Profile


@api_view(['GET'])
def profile_list(request):
    queryset = Profile.objects.all()
    # 注意:这里需要带上 context={'request': request}
    serializer = ProfileSerializer(queryset, many=True, context={'request': request})
    return Response(serializer.data)


@api_view(['GET'])
def profile_detail(request, id):
    instance = Profile.objects.get(id=id)
    serializer = ProfileSerializer(instance, context={'request': request})
    return Response(serializer.data)


@api_view(['GET'])
def user_list(request):
    queryset = User.objects.all()
    serializer = UserSerializer(queryset, many=True, context={'request': request})
    return Response(serializer.data)


@api_view(['GET'])
def user_detail(request, id):
    instance = User.objects.get(id=id)
    serializer = UserSerializer(instance, context={'request': request})
    return Response(serializer.data)

设置 URL:

from django.conf.urls import url
from django.contrib import admin
from myApp.views import profile_list, profile_detail, user_detail, user_list

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # name 参数和序列化器的 lookup_field 对应
    url(r'^api/profile_list/', profile_list, name='profile-list'),
    url(r'^api/profile/(?P<id>[0-9])/$', profile_detail, name='profile-detail'),

    url(r'^api/user_list/', user_list, name='user-list'),
    url(r'^api/user/(?P<id>[0-9])/$', user_detail, name='user-detail'),
]

现在序列化后的 User 对象是这样的:

{
    "url": "http://127.0.0.1:8000/api/user/1/",
    "username": "diego",
    "email": "",
    "user_profile": {
        "url": "http://127.0.0.1:8000/api/profile/1/",
        "city": "guangzhou",
        "owner": "http://127.0.0.1:8000/api/user/1/"
    }
}

序列化后的 Profile 对象:

{
    "url": "http://127.0.0.1:8000/api/profile/1/",
    "city": "guangzhou",
    "owner": "http://127.0.0.1:8000/api/user/1/"
}

提示:正确地匹配超链接和 URL conf 有时可能有点困难。打印 HyperlinkedModelSerializer 实例的 repr 是一种特别有用的方法,可以准确检查这些关系预期映射的 view_namelookup_field




我们可以显式设置序列化类中的字段。例如:

# serializers.py

from rest_framework import serializers
from myApp.models import Profile
from django.contrib.auth.models import User


class ProfileSerializer(serializers.HyperlinkedModelSerializer):

    url = serializers.HyperlinkedIdentityField(
            view_name='profile-detail',
            lookup_field='id'
        )

    owner = serializers.HyperlinkedIdentityField(
            view_name='user-detail',
            lookup_field='id'
        )

    class Meta:
        model = Profile
        fields = ( 'url', 'city', 'owner')


class UserSerializer(serializers.HyperlinkedModelSerializer):
    user_profile = ProfileSerializer()
    url = serializers.HyperlinkedIdentityField(
            view_name='user-detail',
            lookup_field='id'
        )

    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'user_profile')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Serializers 序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可...
    lkning阅读 4,731评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,174评论 19 139
  • 你好 Django REST Framework 在第二章,我们学习了 REST 开发的基本知识,并且在没有借助任...
    ucag阅读 9,971评论 5 16
  • “饭要按时吃,工作不要太拼命,晚上早点睡,还有……”耳边传来妈妈第一百零八遍絮叨的叮咛,我一边收拾行李,一边忙点...
    渺渺籽阅读 1,531评论 0 0
  • “At least I tried,At least I did that.(至少我去尝试了,至少我去做了。)” ...
    落小北coco阅读 4,748评论 0 1

友情链接更多精彩内容