一旦我覆盖Django视图集中的list方法,图像字段URL就会改变

时间:2015-09-11 11:45:40

标签: python django image rest

我是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。

帮助!

1 个答案:

答案 0 :(得分:1)

默认情况下,ModelViewSet将请求传递到序列化程序,因此序列化程序可以根据当前域构建URL。如果没有请求,EntrySerializer就不知道域名,因此它会创建无域网址。

您可以通过多种方式解决问题:

  1. 而不是覆盖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)
    
  2. 使用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)
    
  3. 将包含当前请求的字典传递给序列化程序的上下文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)
    
  4. 最推荐使用第一种方法,最不推荐使用最后一种方法,因为ModelViewSet中有更多默认方法不会受到list方法内部更改的影响。此外,默认情况下还会在序列化程序中传递更多默认变量。