Python 如何避免在序列化程序django中获得双数组?

Python 如何避免在序列化程序django中获得双数组?,python,django,api,Python,Django,Api,我试图返回与作者相关的所有书籍的所有引用,但是,我在数组中得到了一个数组,我知道它是因为序列化程序中的foo,以及ArrayField(models.URLField(),但是我想作为字符串而不是数组返回 注意:API是只读的,因此可写字段无关紧要 class Books(models.Model): id = models.CharField(max_length=255) summary = models.TextField(blank=True, null=True)

我试图返回与作者相关的所有书籍的所有引用,但是,我在数组中得到了一个数组,我知道它是因为序列化程序中的
foo
,以及
ArrayField(models.URLField()
,但是我想作为字符串而不是数组返回

注意:API是只读的,因此可写字段无关紧要

class Books(models.Model):
    id = models.CharField(max_length=255)
    summary = models.TextField(blank=True, null=True)
    last_modified = models.DateTimeField(auto_now=True)

class References(models.Model):
    bookid = models.ForeignKey(Books, on_delete=models.SET_NULL, null=True)
    references = ArrayField(models.URLField(),null=True, blank=True, default=list)


serializer

class ReferencesSerializer(serializers.ModelSerializer):
    class Meta:
        model = References
        fields = ("references",)


class BooksSerializer(serializers.ModelSerializer):
    foo = serializers.SerializerMethodField()

    class Meta:
        model = Books
        fields = ('id','summary','foo', 'last_modified',)

    def get_foo(self, value):
        items = References.objects.filter(bookid=value)
        serializer = ReferenceSerializer(instance=items, many=True)
        return serializer.data

viewset

class BooksViewSet(mixins.ListModelMixin,
                      viewsets.GenericViewSet):

    queryset = Books.objects.all()
    serializer_class = BooksSerializer

    def get_queryset(self):
        search = self.request.query_params.get('search', None)
        if search is not None:
            self.queryset = self.queryset.filter(
                Q(summary__icontains=search) | Q(id__iexact=search)
            )
        return self.queryset
回应

{
   "count":1,
   "next":null,
   "previous":null,
   "results":[
      {
         "id":"2021-3420",
         "summary":"",
         "foo":[
            [
               "www.google.com",
               "gksjksjs.com"
            ]
         ],
         "last_modified":"2021-03-06T00:41:00Z"
      }
   ]
}

只返回第一个元素,而不是返回完整的序列化程序数据

def get_foo(self, value):
    items = References.objects.filter(bookid=value)
    serializer = ReferenceSerializer(instance=items, many=True)
    return serializer.data[0] if serializer.data else ''
def get_foo(self,value):
items=引用.对象.过滤器(bookid=值)
序列化器=引用序列化器(实例=项,多个=真)

如果serializer.data else“”,则返回serializer.data[0]
您可以将
覆盖到
BooksSerializer的
方法以获得所需的输出

class BooksSerializer(serializers.ModelSerializer):
    foo = serializers.SerializerMethodField()

    class Meta:...
        
    def get_foo(self, value):...

    def to_representation(self, instance):
        serialized_instance = super().to_representation(instance)
        serialized_instance['foo'] = ' '.join(serialized_instance['foo'][0])
        return serialized_instance

另一种方法是使用查询集的
values\u list
方法。
flat=True
将完成这项工作

注意:如果要序列化多个字段,不幸的是,flat=True选项不是这种情况。但是从您的示例来看,您似乎只想使用一个引用“字段

注2:Itertools是一种非常快速且优雅的方法,适用于此类情况。下一步,您可以使结果变得平坦

import itertools
    
def get_foo(self, value):
    qs = list(References.objects.values_list("references", flat=True)) 
    qs_flat = list(itertools.chain(*qs))
    return qs_flat

问题很简单,
书籍
的一个实例可以与
引用
的多个实例相关,因为
引用
有一个
外键
书籍
。这可能是您的模型设计问题,或者将外键更改为一对一字段,或者将
数组字段
更改为simply a
URLField
。每本书都有多个引用。这就是为什么ArrayField(url)
references
有一个
ForeignKey
books
已经意味着一种多对一的关系。在这种情况下,您仍然为多个值放置一个数组。现在明白这一点了吗?确切地说,多对一,但我想避免得到数组[array[]]请阅读问题是
“foo”:[[“www.google.com”,“gksjksjs.com”]
当我想要
“foo”:[“www.google.com”,“gksjksjs.com”]
@anaosuna我已经更新了答案。Itertools将帮助下一步。问题是“foo”:[[“www.google.com”,“gksjksjjs.com”]]当我想要“foo”:“www.google.com”,“gksjksjjs.com”]@anaosuna检查我的另一个答案。@VishalSingh可能你应该删除一个答案并用另一个的内容更新一个。@ruddra不清楚op需要什么,这就是我添加另一个答案的原因。op给我确认后,我将删除其中一个。