所有
我无法将我的模型的关系字段之一显示为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时,我收到以下错误:
/ api / tracks /
中的AssertionError
HyperlinkedRelatedField
需要序列化程序上下文中的请求。在实例化序列化程序时添加context={'request': request}
。
有什么想法吗?
答案 0 :(得分:7)
正如@zymud所说,您应该将序列化器更改为serializer = AlbumSerializer(album, context={'request': request})
和AlbumList
视图中的AlbumDetail