欢迎来访我的博客。

Django Rest Framework学习总结-5:给关联的API添加超链接

Django 小张哥哥 2309浏览 25评论

当前,我们的API之间的关系还是通过主键相联系的。在本文,我们将通过使用超链接让我们的API之间的联系更加紧密,更加方便我们使用。


为API创建一个endpoint

现在我们的snippetsusers已经有了endpoint,但是我们的API还没有一个单独的入口。
我们使用一个常规的函数视图和@api_view的装饰器去创建一个。
在snippets/views.py文件中写入:


from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse


@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'snippets': reverse('snippet-list', request=request, format=format)
    })

其中,两点需要注意:一是为了返回全长的URL信息,我们使用了REST framework的reverse方法;二是URL的patterns可以很方便的根据名称来区分,这个名称我们后面会在snippets/urls.py中声明。


为高亮的代码片段创建一个endpoint

另外一个比较明显的事情是我们的代码高亮的endpoint还没有实现。
不像其它的API endpoints,我们不想使用JSON,而是使用HTML格式。REST framework提供了两种风格的HTML渲染方式。一个是使用模板templates渲染,另一个是使用预先渲染的HTML(Pre-rendered HTML)。在此,我们就使用第二个。

在创建代码高亮视图的时候,还有一点我们需要考虑到,我们没有现成可用的通用视图。我们返回的不是一个对象实例,而是一个对象实例的属性。

在此,我们就不适用通用视图,我们使用积累GenericAPIView来呈现实例,并自定义.get()方法。
snippets/views.py文件中添加:


from rest_framework import renderers
from rest_framework.response import Response
class SnippetHighlight(generic.GenericAPIView):
    queryset = Snippet.objects.all()
    renderer_classes = [renderer.StaticHTMLRenderer]

    def get(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

同样,我们需要在我们的URLconf中添加这个新视图。我们给API root添加一个urlpattern
在snippets/urls.py文件中添加:


path('', views.api_root),

然后为snippet高亮添加一个url pattern


path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view()),


为API添加超链接

处理各个项之间的关系是我们API设计中一个很有挑战性的方面。为各个项之间添加关系,我们有很多种方法可以选择:

  1. 使用主键;

  2. 使用超链接

  3. 在关联的项中使用一个特定的可以确定身份的slug field;

  4. 使用关联的项的默认的字符串表达形式;

  5. 将关联项嵌套在parent representation中;

  6. 其它的一些用户自定义的表现方法。

REST framework支持所有这些方法。
我们在此就使用超链接形式。
为此,我们需要修改一下serializers,继承自HyperlinkedModelSerializer而不是ModelSerializer

HyperlinkedModelSerializerModelSerializer有一下几点不同:

  1. 前者默认不包含id域;

  2. 前者引入一个url域;

  3. 关系使用HyperlinkedRelatedField,而不是PrimaryKeyRelatedField

我们在此可以重写一下我们的序列化器。
修改snippets/serializers.py文件,添加:


class SnippetSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')

    class Meta:
        model = Snippet
        fields = ('url', 'id', 'highlight', 'owner', 
                  'title', 'code', 'linenos', 'language', 'style')
                  
                  
class UserSerializer(serializers.HyperlinkedModelSerializer):
    snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail',read_only=True)

    class Meta:
        model = User
        fields = ('url', 'id', 'username', 'snippets')


为URL pattern命名

为了得到超链接的API,我们需要保证给每一个URL pattern命名,我们看一看如何给它们命名。

  1. API的根指向'user-list'和'snippet-list'

  2. snippet序列化器中包括一个域指向'snippet-highlight',

  3. user的序列化器包含一个域指向'snippet-field'

  4. snippet和user序列化器中有一个'url'域默认指向'{model_name}-detail',即'snippet-detail'和'user-detail'

将这些名字添加到我们的snippets/urls文件中后,我们的的文件如下:


from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from .views import SnippetList, SnippetDetail, UserList, UserDetail, api_root, SnippetHighlight

urlpatterns = [
    path('', api_root),
    path('snippets/', SnippetList.as_view(), name='snippet-list'),
    path('snippet/<int:pk>/', SnippetDetail.as_view(), name='snippet-detail'),
    path('users/', UserList.as_view(), name='user-list'),
    path('user/<int:pk>/', UserDetail.as_view(), name='user-detail'),
    path('snippets/<int:pk>/highlight/', SnippetHighlight.as_view(), name='snippet-highlight'),
]

urlpatterns = format_suffix_patterns(urlpatterns)


分页

我们的用户和代码片段页面可能会被服务器返回得到很多的实例信息,因此我们需要对结果进行翻页,并且允许API在各个不同的页面之间跳转。

我们可以直接修改项目文件夹下的settings.py文件,添加如下内容:


REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10}

注意,所有的REST framework相关的配置信息都存储在REST_FRAMEWORK字典下。
我们也可以自定义分页的显示效果。如果没有特殊需要,我们直接使用默认的即可。


浏览器查看

现在我们打开浏览器查看我们的API,现在发现,我们可以直接通过点击API的链接进行跳转了。

django_rest_framework_051.png

另外,我们在snippet实例页面也可以看到有个'highlight'链接,点击之后,我们高亮效果之后的代码片段了。

django_rest_framework_052.png



本文中的源码可以在Github上查看。点我查看本文源码




转载请注明:禅思 » Django Rest Framework学习总结-5:给关联的API添加超链接?

喜欢 (0) or 分享 (0)

我的个人微信公众号,欢迎关注

扫码或搜索:Python后端开发Django

Python后端开发Django

微信公众号 扫一扫关注

结交朋友、一起学习,一起进步。

科波之主

QQ号 386046154 立即加入

添加微信,进行技术交流

专注技术交流, 一同成长进步

我的微信号

如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(25)个小伙伴在吐槽
    1. generic for amoxicillin amoxil - price of amoxicillin without insurance
      WilliamPex 2021-06-21 11:19:57 回复
      • doxy generic doxycycline - doxycycline
        WilliamPex 2021-06-22 06:54:14 回复
        • order amoxicillin no prescription amoxicillin generic - generic amoxicillin cost
          WilliamPex 2021-06-23 01:34:02 回复