LOADING

Follow me

Django RESTframework(官方教程之三)
十一月 30, 2013|Whistler

Django RESTframework(官方教程之三)


  1. 跟着Django的教程走例子,遇到了Django REST Framework的内容,可惜教程用的版本有点老,在Django1.5,Python3.3下例子都通不过。在http://django-rest-framework.org的官网上有教程,我看了看,似乎只有前两部分的中文翻译,就趁着自己看也翻一下后面的部分,自己学习,供大家参考:如有错讹,请多指教。

  1. 原始来源:http://django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis.html
  2.  
  3. 教程 5 – 关系 & 超链接API
  4. 到目前为止,在我们的API中关系(relationship)还是通过主键来表示的。在这部分的教程中,我们将用超链接方式来表示关系,从而提升API的统一性和可发现性。
  5. 为API根创建一个endpoint
  6. 到目前为止,我们已经有了’snippets’和’users’的endpoint, 但是我们还没有为我们的API单独创立一个端点入口。我们可以用常规的基于函数的view和之前介绍的 @api_view 修饰符来创建。
  7. 复制代码
  8. from rest_frameworkimport
    renderers
  9. from rest_framework.decoratorsimport
    api_view
  10. from rest_framework.responseimport
    Response
  11. from rest_framework.reverseimport
    reverse

  12. @api_view((GET,))
  13. def api_root(request, format=None):
  14.     return
    Response({
  15.         users:
    reverse(
    user-list,
    request=request, format=
    format),
  16.         snippets:
    reverse(
    snippet-list,
    request=request, format=
    format)
  17.     })
  18. 复制代码
  19.  
  20. 请注意,我们用 REST framework 的 reverse 函数来返回完全合规的URLs.
  21. 为高亮的Snippet创建一个endpoint
  22. 我们目前还没有为支持代码高亮的Snippet创建一个endpoints.
  23. 与之前的API endpoints不同, 我们将直接使用HTML呈现,而非JSON。在 REST framework中有两种风格的HTML render, 一种使用模板来处理HTML,一种则使用预先处理的方式。在这里我们使用后者。
  24. 另一个需要我们考虑的是,对于高亮代码的view并没有具体的泛型view可以直接利用。我们将只返回实例的一个属性而不是对象实例本身。
  25. 没有具体泛型view的支持,我们使用基类来表示实例,并创建我们自己的 .get() 方法。在你的 snippets.views 中增加:
  26. 复制代码
  27. from rest_frameworkimport
    renderers
  28. from rest_framework.responseimport
    Response

  29. class SnippetHighlight(generics.SingleObjectAPIView):
  30.     model= Snippet
  31.     renderer_classes= (renderers.StaticHTMLRenderer,)

  32.     def get(self, request,
    *args, **
    kwargs):
  33.         snippet= self.get_object()
  34.         return Response(snippet.highlighted)
  35. 复制代码
  36.  
  37. 和以往一样,我们需要为新的view增加新的URLconf,如下增加urlpatterns:
  38. url(r^$,api_root),
  39. 还需要为代码高亮增加一个urlpatterns:
  40. url(r^snippets/(?P<pk>[0-9]+)/highlight/$,
    views.SnippetHighlight.as_view()),
  41.  
  42. API超链接化
  43. 在Web API设计中,处理实体间关系是一个有挑战性的工作。我们有许多方式来表示关系:
  44. 使用主键;
  45. 使用超链接;
  46. 使用相关实体唯一标识的字段;
  47. 使用相关实体的默认字符串表示;
  48. 在父级表示中嵌入子级实体;
  49. 其他自定义的表示。
  50. REST framework支持所有这些方式,包括正向或者反向的关系,或者将其应用到自定义的管理类中,例如泛型外键。
  51. 在这部分,我们使用超链接方式。为了做到这一点,我们需要在序列化器中用 extendHyperlinkedModelSerializer 来替代之前的 ModelSerializer.
  52. HyperlinkedModelSerializer 与 ModelSerializer 有如下的区别:
  53. 缺省状态下不包含 pk 字段;
  54. 具有一个 url 字段,即HyperlinkedIdentityField类型.
  55. 用HyperlinkedRelatedField表示关系,而非PrimaryKeyRelatedField.
  56. 我们可以很方便的改写现有代码来使用超连接方式:
  57. 复制代码
  58. class SnippetSerializer(serializers.HyperlinkedModelSerializer):
  59.     owner= serializers.Field(source=owner.username)
  60.     highlight= serializers.HyperlinkedIdentityField(view_name=snippet-highlight,
    format=
    html)

  61.     class
    Meta:
  62.         model= models.Snippet
  63.         fields= (url,highlight,owner,
  64.                   title,code,linenos,language,style)

  65. class UserSerializer(serializers.HyperlinkedModelSerializer):
  66.     snippets= serializers.HyperlinkedRelatedField(many=True, view_name=snippet-detail)

  67.     class
    Meta:
  68.         model= User
  69.         fields= (url,username,snippets)
  70. 复制代码
  71.  
  72. 注意:我们也增加了一个新的 ‘highlight’ 字段。该字段与 url 字段相同类型。不过它指向了 ‘snippet-highlight’的 url
    pattern, 而非
    ‘snippet-detail’ 的url pattern.
  73. 因为我们已经有一个 ‘.json’的后缀,为了更好的表明高亮字段链接的区别,使用一个 ‘.html’ 的后缀。
  74. 正确使用URL patterns
  75. 如果要使用超链接API,就必须确保正确的命名和使用 URL patterns. 我们来看看我们需要命名的 URL patterns:
  76. 指向 ‘user-list’ 和 ‘snippet-list’ 的API根.
  77. snippet的序列化器,包括一个 ‘snippet-highlight’字段.
  78. user序列化器,包含一个 ‘snippet-detail’字段.
  79. snippet 和user的序列化器,包含 ‘url’ 字段(会缺省指向’snippet-detail’ 和 ‘user-detail’.
  80. 一番工作之后,最终的 ‘urls.py’ 文件应该如下所示:
  81. 复制代码
  82. # API endpoints
  83. urlpatterns = format_suffix_patterns(patterns(snippets.views,
  84.     url(r^$,api_root),
  85.     url(r^snippets/$,
  86.         views.SnippetList.as_view(),
  87.         name=snippet-list),
  88.     url(r^snippets/(?P<pk>[0-9]+)/$,
  89.         views.SnippetDetail.as_view(),
  90.         name=snippet-detail),
  91.     url(r^snippets/(?P<pk>[0-9]+)/highlight/$,
  92.         views.SnippetHighlight.as_view(),
  93.         name=snippet-highlight),
  94.     url(r^users/$,
  95.         views.UserList.as_view(),
  96.         name=user-list),
  97.     url(r^users/(?P<pk>[0-9]+)/$,
  98.         views.UserDetail.as_view(),
  99.         name=user-detail)
  100. ))

  101. # Login and logout views for the browsable API
  102. urlpatterns += patterns(,
       
  103.     url(r^api-auth/,
    include(
    rest_framework.urls,
  104.                                namespace=rest_framework)),
  105. )
  106. 复制代码
  107.  
  108. 添加分页
  109. 列表view有时会返回大量的实例结果,所以我们应该把结果分页显示,以便用户使用。
  110. 通过在 settings.py 中添加如下配置,我们就能在结果列表中增加分页的功能:
  111. REST_FRAMEWORK ={PAGINATE_BY:10}
  112. 请注意REST framework的所有配置信息都是存放在一个叫做 ‘REST_FRAMEWORK’的dictionary中,以便于其他配置区分。
  113. 如有必要,你也可以自定义分页的方式,这里不再赘述。
  114. 回顾我们的工作
  115. 如果我们打开浏览器来看看之前的API,会发现它们可以用链接的方式工作了。
  116. 当你查看snippet实例的 ‘highlight’ 链接时,你会直接看到代码高亮的HTML呈现。
  117. 我们目前已经完成了全套的Web API。可以浏览,支持认证,对象粒度的权限,以及多种返回格式。
  118. 我们已经完成了流程中的所有步骤,了解了如何从基本的Django View出发,根据需求逐步定义我们的工作方式。
  119. 你能从GitHub上得到教程的最终代码: tutorial
    code
     ,或者直接访问在线示例: the sandbox.


版权声明:本文为博主原创文章,未经博主允许不得转载。

no comments
Share

发表评论