使用 Django 为 API POST 请求更改 JSON 数据的结构

Change structure of JSON data for API POST request with Django

我有一个具有此结构的 Django REST API 端点,我需要 post 到外部 API:

{
    "body": [
        "...",
        "...",
        "...",
    ],
    "title": [
        "...",
        "...",
        "...",
    ],
    "id": [
        "...",
        "...",
        "...",
    ]
}

'body' 下的第一项与 'title' 和 'id' 下的第一项相匹配,依此类推。

我遇到的问题是,有问题的 API 需要具有以下结构的 JSON 数据:

{
  "texts": [
    {
      "body": "...",
      "title": "...",
      "id": "..."
    },
    {
      "body": "...",
      "title": "...",
      "id": "..."
    },
    {
      "body": "...",
      "title": "...",
      "id": "..."
    },
  ],
  "language": "EN",
}

而且我无法弄清楚我的端点如何反映该结构,将 bodiestitlesids 分组在一起,这些分组嵌套在 texts,并在末尾附加 language 参数。

我在 views.py 中使用的序列化程序如下所示:

class MyReasonsSerializer(serializers.Serializer):
    body = serializers.SerializerMethodField()
    title = serializers.SerializerMethodField()
    id = serializers.SerializerMethodField()

    def get_body(self, obj):
        return obj.reasons.order_by('transaction_date').values_list('body', flat=True)

    def get_title(self, obj):
        return obj.reasons.order_by('transaction_date').values_list('title', flat=True)

    def get_id(self, obj):
        return obj.reasons.order_by('transaction_date').values_list('transaction_date', flat=True)

class ReasonsData(RetrieveAPIView):
    queryset = Market.objects.all().prefetch_related('reasons')
    authentication_classes = []
    permission_classes = []
    serializer_class = MyReasonsSerializer

提前感谢您的任何建议!

编辑:

以下是模型:

class Market(models.Model):
    title = models.CharField(max_length=50, default="")
    current_price = models.DecimalField(max_digits=5, decimal_places=2, default=0.50)
    description = models.TextField(default="")
    ...
    language = models.CharField(max_length=2, default="EN")

    def __str__(self):
        return self.title[:50]

class Reason(models.Model):
    user_id = models.ForeignKey('users.CustomUser',
        on_delete=models.CASCADE,
        related_name='user_reasons',
        default=None)
    market = models.ForeignKey(
        Market,
        on_delete=models.CASCADE,
        related_name='reasons',
        default=None)
    ...
    valence = models.CharField(max_length=11, default="")
    title = models.TextField(default="")
    body = models.TextField(default="")

    def __str__(self):
        return str(self.title)

我会这样构造它...(如果不看模型并尝试一下,很难准确知道)

class ReasonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Reason
        fields = ("id", "body", "title")

class MarketSerializer(serializers.Serializer):
    texts = ReasonSerializer(many=True, source="reasons")
    language = serializers.CharField()

    class Meta:
        model = Market

class ReasonsData(RetrieveAPIView):
    queryset = Market.objects.all()
    authentication_classes = []
    permission_classes = []
    serializer_class = MarketSerializer

    def get_queryset(self):
        qs = super().get_queryset()

        # filter queryset by valence if passed as a query param
        # ?valence=something
        valence = self.request.query_params.get("valence", None)
        if valence is not None:
            qs = qs.filter(reasons__valence=valence)

        return qs