Django Rest框架:从嵌套结构中获取唯一的值列表

Django Rest框架:从嵌套结构中获取唯一的值列表,django,django-rest-framework,Django,Django Rest Framework,我希望能够从深度嵌套的数据结构中返回字符串列表。在这个场景中,我有一个API来管理一系列书店,这些书店位于不同的地区 目前,我有一个API端点,它接受一个区域的ID,并返回一个嵌套的JSON结构,其中包含关于该区域、各个书店以及每个书店中可以找到的书籍的详细信息 { "region": [ { "store": [ { "book": { "n

我希望能够从深度嵌套的数据结构中返回字符串列表。在这个场景中,我有一个API来管理一系列书店,这些书店位于不同的地区

目前,我有一个API端点,它接受一个区域的ID,并返回一个嵌套的JSON结构,其中包含关于该区域、各个书店以及每个书店中可以找到的书籍的详细信息

{
  "region": [
    {
      "store": [
        {
          "book": {
            "name": "Foo"
          }
        },
        {
          "book": {
            "name": "Bar"
          }
        },
        {
          "book": {
            "name": "Baz"
          }
        }
      ],
    },
    {
      "store": [
        {
          "book": {
            "name": "Foo"
          }
        },
        {
          "book": {
            "name": "Bar"
          }
        }
      ],
    },
    {
      "store": [
        {
          "book": {
            "name": "Foo"
          }
        },
        {
          "book": {
            "name": "Baz"
          }
        },
        {
          "book": {
            "name": "Qux"
          }
        }
      ]
    }
  ]
}
我的模型如下所示。我知道这些模型对于这个人为的例子来说意义不大,但它确实反映了我的真实世界代码:

class Book(TimeStampedModel):
    name = models.CharField(default="", max_length=512)


class Bookstore(TimeStampedModel):
    value = models.CharField(default="", max_length=1024)
    book = models.ForeignKey(Book, on_delete=models.CASCADE)


class Region(TimeStampedModel):
    stores = models.ManyToManyField(Bookstore)


class BookstoreChain(TimeStampedModel):
    regions = models.ManyToManyField(Region)
我为上述响应创建的序列化程序如下所示:

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"


class BookstoreSerializer(serializers.ModelSerializer):
    books = BookSerializer()

    class Meta:
        model = Bookstore
        fields = "__all__"


class RegionSerializer(serializers.ModelSerializer):
    stores = BookstoreSerializer(many=True)

    class Meta:
        model = Region
        fields = "__all__"


class BookstoreChainSerializer(serializers.ModelSerializer):
    regions = RegionSerializer(many=True)

    class Meta:
        model = BookstoreChain
        fields = "__all__"
{
    "books": [
        "Foo",
        "Bar",
        "Baz",
        "Qux"
    ]
}
我不确定这个解决方案的视图或序列化程序应该是什么样子。我更熟悉编写原始SQL或使用ORM/Linq获得一组结果

虽然上面的响应非常有用,但我真正想要的是API端点返回在给定区域中可以找到的图书名称的唯一列表(
Foo
Bar
Baz
Qux
)。我希望我的回答是:

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"


class BookstoreSerializer(serializers.ModelSerializer):
    books = BookSerializer()

    class Meta:
        model = Bookstore
        fields = "__all__"


class RegionSerializer(serializers.ModelSerializer):
    stores = BookstoreSerializer(many=True)

    class Meta:
        model = Region
        fields = "__all__"


class BookstoreChainSerializer(serializers.ModelSerializer):
    regions = RegionSerializer(many=True)

    class Meta:
        model = BookstoreChain
        fields = "__all__"
{
    "books": [
        "Foo",
        "Bar",
        "Baz",
        "Qux"
    ]
}
到目前为止,我微弱的尝试有一个带有以下路径的
url.py

path(“api/regions//uniqueBooks/”,views.UniqueBooksForRegionView.as_view(),name=“uniqueBooksForRegion”)

我的
views.py
看起来像:

class UniqueBooksForRegionView(generics.RetrieveAPIView):
    queryset = Regions.objects.all()
    serializer_class = ???

因此,你从地区开始你必须得到商店,这样你就可以过滤商店中的书籍,这里有一个解决方案,它会起作用

注: 避免在
*APIView
中使用
.get()
,因为如果请求没有ID,它将触发错误。您可以使用
get\u object\u或\u 404()
,但不能在Sentry中记录错误

要从
*APIView
获取元素,请使用
过滤器()


这里是流程,代码可能需要一些调整,但我希望它可以帮助您理解流程

您可以发布一个您希望获得的输出示例吗?另外,添加您的模型可能也会有所帮助。@NavidZarepak,我编辑了上面的问题以包含请求信息。希望这足以让我了解我不了解的内容,从而解决我的问题。您希望该响应作为名为
books
的字段上的
bookstoresializer
响应的一部分吗?我不太清楚响应的确切外观,我只需要一个易于迭代的书名列表。这一行有一些问题:
stores\u qs=Region.objects.filter(pk=filter(uid=self.kwargs[self.lookup\u field])).stores.set()
。我得到一个错误
filter()不接受关键字参数
pk=filter(…)
应该使用Python的filter函数还是Django的filter函数?@roundtheworld sry man my bad Region.objects.filter(pk=self.kwargs[self.lookup_field]).stores.set()这是一个打字错误,这更有意义。两个后续问题:1。我在
stores\u qs
行中得到一个错误,它说:
'QuerySet'对象没有属性'stores'
2。不
set()
获取参数吗?@roundtheworld sry再次mb我无法验证代码在Region.objects.filter(pk=self.kwargs[self.lookup\u field])中写得很快。stores\u set.all()将返回所需的数据HMM,添加
\u set
会导致错误
'Region'对象没有属性“stores\u set”
…但是如果我从您的示例中删除
\u set
,代码会像我希望的那样工作。