【问题标题】:How to add an url field to a serializer with Django Rest Framework如何使用 Django Rest Framework 将 url 字段添加到序列化程序
【发布时间】: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"
       },

    ]

【问题讨论】:

标签: python django django-rest-framework django-urls


【解决方案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')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多