我是python的新手,所以django。我在模型中添加了一个图像字段......
class Entry(models.Model):
title = models.CharField(max_length=255)
body = MarkdownField()
image = models.ImageField(upload_to='images',null=True,blank=True)
然后,当我像我所说的那样编写简单的django休息视图时,它可以正常工作。
class EntryView(viewsets.ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntrySerializer
此处,django rest API中的图像字段显示为:
" image":" http://localhost:8000/media/images/x_4.jpg",
现在,当我在视图中覆盖列表mthod服务器url部分,即" http://localhost:8000"已经离开,剩下的就剩下了。 我提到的新观点是:
class EntryView(viewsets.ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntrySerializer
lookup_field = 'title'
def list(self, request,*kwargs):
queryset=Entry.objects.filter(publish=True)
serializer = EntrySerializer(queryset,many=True)
return Response(serializer.data)
如上所述,和django rest API中的图像字段变为:
" image":" /media/images/x_4.jpg" ;,
当我覆盖列表方法时,我希望API中的图像字段中有完整的URL。
帮助!
答案 0 :(得分:1)
默认情况下,ModelViewSet
将请求传递到序列化程序,因此序列化程序可以根据当前域构建URL。如果没有请求,EntrySerializer
就不知道域名,因此它会创建无域网址。
您可以通过多种方式解决问题:
而不是覆盖list
方法,覆盖get_queryset,如下所示:
class EntryView(viewsets.ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntrySerializer
lookup_field = 'title'
def get_queryset(self):
return super(EntryView, self).filter(publish=True)
使用ModelViewSet的get_serializer方法而不是直接使用EntrySerializer:
class EntryView(viewsets.ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntrySerializer
lookup_field = 'title'
def list(self, request,*kwargs):
queryset=Entry.objects.filter(publish=True)
serializer = self.get_serializer(queryset,many=True)
return Response(serializer.data)
将包含当前请求的字典传递给序列化程序的上下文kwarg:
class EntryView(viewsets.ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntrySerializer
lookup_field = 'title'
def list(self, request,*kwargs):
queryset=Entry.objects.filter(publish=True)
serializer = EntrySerializer(queryset,many=True, context={'request': request})
return Response(serializer.data)
最推荐使用第一种方法,最不推荐使用最后一种方法,因为ModelViewSet中有更多默认方法不会受到list方法内部更改的影响。此外,默认情况下还会在序列化程序中传递更多默认变量。