如何使用 Django Rest Framework 将 url 字段添加到序列化程序

Posted

技术标签:

【中文标题】如何使用 Django Rest Framework 将 url 字段添加到序列化程序【英文标题】:How to add an url field to a serializer with Django Rest Framework 【发布时间】:2016-08-10 08:59:17 【问题描述】:

我正在关注Django Rest Framework - Tutorial 3 Class based views 上的教程。

如何将 url 字段(指向当前的 sn-p)添加到序列化程序中?

serializers.py

from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
from django.core.urlresolvers import reverse

class SnippetSerializer(serializers.ModelSerializer):

    class Meta:
        model = Snippet
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')

urls.py

urlpatterns = [
    url(r'^snippets/$', views.SnippetList.as_view()),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
]

实际输出

[  
     
      "id":1,
      "title":"",
      "code":"foo = \"bar\"\n",
      "linenos":false,
      "language":"python",
      "style":"friendly"
   
]

所需的输出

[  
         
          "id":1,
          "url":"http://192.168.28.131:8000/snippets/1/",
          "title":"",
          "code":"foo = \"bar\"\n",
          "linenos":false,
          "language":"python",
          "style":"friendly"
       ,

    ]

【问题讨论】:

只要你遵循命名约定或者有命名的url:django-rest-framework.org/api-guide/reverse 【参考方案1】:

您必须使用HyperlinkedModelSerializer 序列化程序和HyperlinkedIdentityField 字段

来自Django Rest Framework documentation

HyperlinkedModelSerializer 类类似于 ModelSerializer 类,除了它使用超链接来表示 关系,而不是主键。网址字段将是 使用HyperlinkedIdentityField 序列化器字段表示,并且 模型上的任何关系都将使用 HyperlinkedRelatedField 序列化器字段。

例如(与您的情况):

class SnippetSerializer(serializers.HyperlinkedModelSerializer):
        url = serializers.HyperlinkedIdentityField(view_name='snippet-detail', read_only=True)

    class Meta:
        model = Snippet
        fields = ('id', 'url', 'title', 'code', 'linenos', 'language', 'style')

当然,view_name 的值必须与在urls.py(或不在其他地方)中声明的用于获取有关 sn-p 的所有信息的 url 的名称匹配。

例如:

# urls.py
urlpatterns = [
    url(r'^snippets/(?P<pk>[0-9]+)$', views.SnippetDetail.as_view(), name='snippet-detail'),
]

【讨论】:

谢谢!我的urls.py 看起来有些不同。它使用views.SnippetDetail.as_view()(复制粘贴自教程)。当我使用你的定义时,我得到__init__() takes exactly 1 argument (3 given) 有什么想法吗? 是的,只需添加一个 name 值。我更新了我的例子。它不起作用,因为您使用基于类的视图。使用这个:url(r'^snippets/(?P&lt;pk&gt;[0-9]+)$', views.SnippetDetail.as_view(), name='snippet-detail')【参考方案2】:

使用视图集时,将完整的反向 url 名称指定为 view_name

class XyzSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='app1:api:xyz-detail',
        read_only=True
    )

    class Meta:
        model = Xyz
        fields = ( 'id', 'url')

【讨论】:

以上是关于如何使用 Django Rest Framework 将 url 字段添加到序列化程序的主要内容,如果未能解决你的问题,请参考以下文章

django.test.client 上的 Django rest 框架导入错误

无法使用 Django Rest 框架发送压缩的 gzip 数据

Django 和 Django 休息框架

Django前后端分离——drf

Django REST to React - 无需密码即可获取社交身份验证令牌

尽管有 AllowAny 权限,django-rest-framework 在 POST、PUT、DELETE 上返回 403 响应