美文网首页
序列化器:HyperlinkedModelSerializer

序列化器:HyperlinkedModelSerializer

作者: SingleDiego | 来源:发表于2018-05-06 17:37 被阅读966次

    官方文档原文

    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')
    

    相关文章

      网友评论

          本文标题:序列化器:HyperlinkedModelSerializer

          本文链接:https://www.haomeiwen.com/subject/azsurftx.html