如何在django-rest-framework中表示`self` url

时间:2015-04-20 08:34:52

标签: django django-rest-framework hateoas

我想添加指向单个资源表示的链接,该表示是自身的网址self。喜欢(摘自文档):

class AlbumSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'track_listing')

{
    'album_name': 'The Eraser',
    'artist': 'Thom Yorke',
    'self': 'http://www.example.com/api/album/2/',
}

应该怎么做?

7 个答案:

答案 0 :(得分:4)

这是我的解决方案,

在你的视图方法中创建像这样的serilizer对象:

album = AlbumSerializer(data=data, {"request":request})
您的serilizer类中的

覆盖to_representation方法(您可以在DRF docs

上阅读此方法
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
    def to_representation(self, obj):
        data = super().to_representation(obj)
        request = self.context["request"]
        return data

答案 1 :(得分:3)

好吧,这解决了我的问题,但如果你有更好的解决方案,请发一个答案:

self_url = serializers.SerializerMethodField('get_self')

def get_self(self, obj):
    request = self.context['request']
    return reverse('album-detail', kwargs={'id': obj.id}, request=request)

答案 2 :(得分:2)

如果您继承Function ShortenText() Dim c As Range Dim lRow As Long Dim NewValue As String lRow = Cells(Rows.Count, 24).End(xlUp).Row For Each c In Range("X1:X" & lRow) Cells(c.Row, 2) = Len(c) If Len(c) > 11 Then NewValue = Trim(InputBox("What would you like to rename the value") Selection.Replace What:=c.Value, Replacement:=NewValue, LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False End If Next c End Function ,则只需将serializers.HyperlinkedModelSerializer字段传递给url即可。请参阅此处的文档:

http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/

答案 3 :(得分:1)

根据此issue,您只需在字段列表中添加“url”即可。

答案 4 :(得分:1)

到目前为止,这里的内容比你在其他答案中得到的更多。关键是传递给序列化器构造函数的context参数和字段中的'url'

http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/

在您的视图集中:

class AlbumViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = Album.objects.all()
        serializer = AlbumSerializer(queryset, many=True, 
                                     context={'request': request})
        return Response(serializer.data)

在序列化程序中:

class AlbumSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'track_listing', 'url')

答案 5 :(得分:1)

如上所述,HyperlinkedModelSerializer将转换您所有的相关字段,并删除资源ID。根据情况,我使用以下解决方案之一。

解决方案1::导入api设置并添加url字段:

有关更多详细信息,请参见URL_FIELD_NAME

from rest_framework.settings import api_settings

class AlbumSerializer(SelfFieldMixin, serializers.ModelSerializer):
    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'track_listing', api_settings.URL_FIELD_NAME)

解决方案2::一个简单的mixin,仅在使用默认字段时有效:

class SelfFieldMixin:
    """
    Adds the self link without converting all relations to HyperlinkedRelatedField
    """

    def get_default_field_names(self, declared_fields, model_info):
        """
        Return the default list of field names that will be used if the
        `Meta.fields` option is not specified.
        """
        default_fields = super().get_default_field_names(declared_fields, model_info)
        return [self.url_field_name, *default_fields]

它可以像

一样使用
class AlbumSerializer(SelfFieldMixin, serializers.ModelSerializer):
    class Meta:
        model = Album
        fields = '__all__'

注意::由于需要进行super()调用,因此需要 Python 3 ,必须在任何之前放置一个混合对象序列化程序类!

附言::要在问题中获得所需的回答,还必须将URL_FIELD_NAME设置为'self'

编辑get_default_field_names必须返回list对象,Meta.exclude才能在ModelSerializers上工作。

答案 6 :(得分:1)

您可以像这样使用HyperlinkedIdentityField

class ThingSerializer(ModelSerializer):
    class Meta:
        model = Thing
        fields = ['self_link', ...]

    self_link = HyperlinkedIdentityField(view_name='thing-detail')

您需要适当地命名路由,但是默认路由器会自动命名(记录在here中)。

正如其他人指出的,HyperlinkedModelSerializer也可以使用。这是因为它会自动使用此字段。参见here