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 aURLField
。每本书都有多个引用。这就是为什么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给我确认后,我将删除其中一个。