python Django中多对多关系的特定字段的序列化列表

b1uwtaje  于 2023-08-02  发布在  Python
关注(0)|答案(2)|浏览(83)

我想要的是一个ManyToMany关系中特定字段的列表,而不是该字段所在字典的列表。
例如,使用下面的代码,我得到如下所示的结果

# models.py

from django.db import models

class Bar(models.Model):
    title = models.CharField(max_length=255)

class Foo(models.Model):
    title = models.CharField(max_length=255)
    bars = models.ManyToManyField(Bar, related_name="foos")

# serializers.py

from rest_framework.serializers import ModelSerializer 
from .models import Bar, Foo

class BarSerializer(ModelSerializer):
    class Meta:
        model = Bar
        fields = ("title",)

class FooSerializer(ModelSerializer):
    bars = BarSerializer(many=True)

    class Meta:
        model = Foo
        fields = ("title", "bars")

# views.py

from rest_framework.generics import ListAPIView
from .serializers import FooSerializer
from .models import Foo

class FooAPIView(ListAPIView):
    queryset = Foo.objects.prefetch_related("bars")
    serializer_class = FooSerializer

字符串
结果:

[
    {
        "title": "foo 1",
        "bars": [
            { "title": "bar title 1" },
            { "title": "bar title 2" },
            { "title": "bar title 3" }
        ]
    },
    {
        "title": "foo 2",
        "bars": [
            { "title": "bar title 4" },
            { "title": "bar title 5" },
            { "title": "bar title 6" }
        ]
    },
    {
        "title": "foo 3",
        "bars": [
            { "title": "bar title 7" },
            { "title": "bar title 8" },
            { "title": "bar title 9" }
        ]
    }
]


但我想要的是bars字段的标题列表。
预期结果:

[
  {
    "title": "foo 1",
    "bars": ["bar title 1", "bar title 2", "bar title 3"]
  },
  {
    "title": "foo 2",
    "bars": ["bar title 4", "bar title 5", "bar title 6"]
  },
  {
    "title": "foo 3",
    "bars": ["bar title 7", "bar title 8", "bar title 9"]
  }
]


有没有什么方法可以做到这一点,而不必覆盖Django方法?

nx7onnlm

nx7onnlm1#

您可以使用serializerMethod字段来实现此目的

class FooSerializer(ModelSerializer):
    bars = serializers.SerializerMethodField()

    class Meta:
        model = Foo
        fields = ("title", "bars")

    def get_bars(self, instance):
        return instance.bars.values_list('title', flat=True)

字符串

piah890a

piah890a2#

试试这个...

from rest_framework import serializers
from .models import *

class BarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bar
        fields = ("title",)

class FooSerializer(serializers.ModelSerializer):
    bars = serializers.SerializerMethodField(read_only= True)

    def get_bars(self,obj):
        bars = [i.title for i in obj.bars.all()]
        return bars

    class Meta:
        model = Foo
        fields = ("title", "bars")

字符串
注意-此解决方案在列表中添加特定Foo的Bar,而不是命中查询

其他解决方案

你可以在model中创建@property并在序列化器中使用它,就像这样……

models.py

class Foo(models.Model):
    title = models.CharField(max_length=255)
    bars = models.ManyToManyField(Bar, related_name="foos")

    @property
    def get_bars(self):
        return [i.title for i in self.bars.all()]

serializers.py

class FooSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Foo
        fields = ("title", "get_bars")

双向输出

x1c 0d1x的数据

相关问题