簡體   English   中英

如何避免在序列化器 django 中獲得雙數組?

[英]how do I avoid getting double array in serializer django?

我正在嘗試返回與作者相關的所有書籍的所有引用,但是,我在數組中得到了一個數組,我知道它是因為序列化程序中的fooArrayField(models.URLField() ,但我想要以字符串而不是 arrays 數組的形式返回。

注意: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"
      }
   ]
}

另一種方法是使用查詢集的values_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

只返回第一個元素而不是返回完整的序列化器數據。

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 ''

您可以覆蓋to_representationBooksSerializer方法以獲得所需的 output。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM