在 Django Rest Framework 中使用 HyperlinkedField 作为序列化程序
Using HyperlinkedField for serializer in Django Rest Framework
全部,
我无法让我的模型的一个关系字段在 Django Rest Framework 中显示为超链接。 (我正在处理 http://www.django-rest-framework.org/api-guide/relations/ 中提供的示例。)这是我的代码:
models.py:
class Album(models.Model):
album_name = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks')
order = models.IntegerField()
title = models.CharField(max_length=100)
duration = models.IntegerField()
class Meta:
unique_together = ('album', 'order')
ordering = ['order']
def __unicode__(self):
return '%d: %s' % (self.order, self.title)
serializers.py:
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.StringRelatedField(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
class TrackSerializer(serializers.ModelSerializer):
# THIS WORKS...
# album = serializers.SlugRelatedField(slug_field="album_name", read_only=True)
# THIS DOES NOT WORK...
album = serializers.HyperlinkedRelatedField(view_name="album-detail", read_only=True)
class Meta:
model = Track
fields = ('album', 'order', 'title', 'duration')
views.py:
@api_view(('GET',))
def api_root(request, format=None):
return Response({
'albums': reverse("album-list", request=request, format=format),
'tracks': reverse("track-list", request=request, format=format),
})
class AlbumList(APIView):
def get(self, request, format=None):
albums = Album.objects.all()
serializer = AlbumSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
album = AlbumSerializer(data=request.data)
if album.is_valid():
album.save()
return Response(album.data, status=status.HTTP_201_CREATED)
else:
return Response(album.errors, status=status.HTTP_400_BAD_REQUEST)
class AlbumDetail(APIView):
def get_object(self, pk):
try:
return Album.objects.get(pk=pk)
except Album.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
album = self.get_object(pk)
serializer = AlbumSerializer(album)
return Response(serializer.data)
def put(self, request, pk, format=None):
album = self.get_object(pk)
serializer = AlbumSerializer(album, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
album = self.get_object(pk)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class TrackList(APIView):
def get(self, request, format=None):
tracks = Track.objects.all()
serializer = TrackSerializer(tracks, many=True)
return Response(serializer.data)
def post(self, request, format=None):
track = TrackSerializer(data=request.data)
if track.is_valid():
track.save()
return Response(track.data, status=status.HTTP_201_CREATED)
else:
return Response(track.errors, status=status.HTTP_400_BAD_REQUEST)
class TrackDetail(APIView):
def get_object(self, pk):
try:
return Track.objects.get(pk=pk)
except Track.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
track = self.get_object(pk)
serializer = TrackSerializer(track)
return Response(serializer.data)
def put(self, request, pk, format=None):
track = self.get_object(pk)
serializer = TrackSerializer(track, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
track = self.get_object(pk)
track.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
urls.py:
urlpatterns = patterns('',
url(r'^api/$', api_root),
url(r'^api/albums/$', AlbumList.as_view(), name="album-list"),
url(r'^api/albums/(?P<pk>[0-9]+)/$', AlbumDetail.as_view(), name="album-detail"),
url(r'^api/tracks/$', TrackList.as_view(), name="track-list"),
url(r'^api/tracks/(?P<pk>[0-9]+)/$', TrackDetail.as_view(), name="track-detail"),
)
urlpatterns = format_suffix_patterns(urlpatterns)
当我在 TrackSerializer 中使用 SlugRelatedField 时,一切都按预期工作。但是当我使用 HyperlinkedRelatedField 时,出现以下错误:
AssertionError at /api/tracks/
HyperlinkedRelatedField
requires the request in the serializer context. Add context={'request': request}
when instantiating the serializer.
有什么想法吗?
正如@zymud 所说,您应该在 AlbumList
和 AlbumDetail
视图
中将序列化器更改为 serializer = AlbumSerializer(album, context={'request': request})
全部,
我无法让我的模型的一个关系字段在 Django Rest Framework 中显示为超链接。 (我正在处理 http://www.django-rest-framework.org/api-guide/relations/ 中提供的示例。)这是我的代码:
models.py:
class Album(models.Model):
album_name = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks')
order = models.IntegerField()
title = models.CharField(max_length=100)
duration = models.IntegerField()
class Meta:
unique_together = ('album', 'order')
ordering = ['order']
def __unicode__(self):
return '%d: %s' % (self.order, self.title)
serializers.py:
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.StringRelatedField(many=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
class TrackSerializer(serializers.ModelSerializer):
# THIS WORKS...
# album = serializers.SlugRelatedField(slug_field="album_name", read_only=True)
# THIS DOES NOT WORK...
album = serializers.HyperlinkedRelatedField(view_name="album-detail", read_only=True)
class Meta:
model = Track
fields = ('album', 'order', 'title', 'duration')
views.py:
@api_view(('GET',))
def api_root(request, format=None):
return Response({
'albums': reverse("album-list", request=request, format=format),
'tracks': reverse("track-list", request=request, format=format),
})
class AlbumList(APIView):
def get(self, request, format=None):
albums = Album.objects.all()
serializer = AlbumSerializer(albums, many=True)
return Response(serializer.data)
def post(self, request, format=None):
album = AlbumSerializer(data=request.data)
if album.is_valid():
album.save()
return Response(album.data, status=status.HTTP_201_CREATED)
else:
return Response(album.errors, status=status.HTTP_400_BAD_REQUEST)
class AlbumDetail(APIView):
def get_object(self, pk):
try:
return Album.objects.get(pk=pk)
except Album.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
album = self.get_object(pk)
serializer = AlbumSerializer(album)
return Response(serializer.data)
def put(self, request, pk, format=None):
album = self.get_object(pk)
serializer = AlbumSerializer(album, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
album = self.get_object(pk)
album.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class TrackList(APIView):
def get(self, request, format=None):
tracks = Track.objects.all()
serializer = TrackSerializer(tracks, many=True)
return Response(serializer.data)
def post(self, request, format=None):
track = TrackSerializer(data=request.data)
if track.is_valid():
track.save()
return Response(track.data, status=status.HTTP_201_CREATED)
else:
return Response(track.errors, status=status.HTTP_400_BAD_REQUEST)
class TrackDetail(APIView):
def get_object(self, pk):
try:
return Track.objects.get(pk=pk)
except Track.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
track = self.get_object(pk)
serializer = TrackSerializer(track)
return Response(serializer.data)
def put(self, request, pk, format=None):
track = self.get_object(pk)
serializer = TrackSerializer(track, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
track = self.get_object(pk)
track.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
urls.py:
urlpatterns = patterns('',
url(r'^api/$', api_root),
url(r'^api/albums/$', AlbumList.as_view(), name="album-list"),
url(r'^api/albums/(?P<pk>[0-9]+)/$', AlbumDetail.as_view(), name="album-detail"),
url(r'^api/tracks/$', TrackList.as_view(), name="track-list"),
url(r'^api/tracks/(?P<pk>[0-9]+)/$', TrackDetail.as_view(), name="track-detail"),
)
urlpatterns = format_suffix_patterns(urlpatterns)
当我在 TrackSerializer 中使用 SlugRelatedField 时,一切都按预期工作。但是当我使用 HyperlinkedRelatedField 时,出现以下错误:
AssertionError at /api/tracks/
HyperlinkedRelatedField
requires the request in the serializer context. Addcontext={'request': request}
when instantiating the serializer.
有什么想法吗?
正如@zymud 所说,您应该在 AlbumList
和 AlbumDetail
视图
serializer = AlbumSerializer(album, context={'request': request})