web-dev-qa-db-ja.com

複数のモデルをシリアル化し、すべてを1つのjson応答で送信Django残りのフレームワーク

この質問は、この質問の穴を拡張して埋めるように求められています: Django REST Framework

私の目標は、htmlコードのさまざまなselectステートメントのオプションを動的に設定するために使用するjsonオブジェクトを返すことです。

モデルaから属性を取得したい、モデルbから別の属性を取得したいなど

次に、属性a、b、cなどのすべての値が必要です。

キーへのJSON配列として値に含まれるため

json = {
    modelA: {'atter1, atter2, atter3}
    modelB: {'atter1, atter2, atter3}
    model..:{you get the point}
}

上で参照した投稿のこの部分は理にかなっています:

class TimelineViewSet(viewsets.ModelViewSet):
    """
    API endpoint that lists all Tweet/article objects in rev-chrono.
    """
    queryset = itertools.chain(Tweet.objects.all(), Article.objects.all())
    serializer_class = TimelineSerializer

これは何ではありません:

class TimelineSerializer(serializers.Serializer):
    pk = serializers.Field()
    title = serializers.CharField()
    author = serializers.RelatedField()
    pub_date = serializers.DateTimeField()

個別のモデル属性を正しいjsonキーに設定するにはどうすればよいですか?

シリアライザーの関係に似ていると思いますが、これらの値は1対1、1対多、または多対多を介して相互に関連していません。値ごとにAPIを作成するのではなく、このすべての情報を一度に取得したいだけです。

私は迷子の少女です。家に帰る道を見つけるのを手伝ってください。

7
user6781560

応答形式を合理的に設計すれば、Django REST Frameworkで簡単に見つけることができます。

現時点では少し曖昧に見えますが、次のような提案をします。

{
    "tweets": [
        {"Tweet_attr_A": value_1, ...},  // first Tweet
        {"Tweet_attr_A": value_2, ...},  // second Tweet
        //etc
    ],
    "articles": [
        {"id": 1, ...},  // first article
        {"id": 2, ...},  // second article
        //etc
    ]
}

これは、次のような3つのシリアライザーで表現できます。

class TweetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tweet

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article

class TimelineSerializer(serializers.Serializer):
    tweets = TweetSerializer(many=True)
    articles = ArticleSerializer(many=True)

http://www.Django-rest-framework.org/api-guide/serializers/#dealing-with-nested-objects

次に、複数のモデルを使用しているため、これをDRFの魔法のModelViewSetタイプに組み込むよりも、独自のカスタムビューセットを定義する方が簡単です。
http://www.Django-rest-framework.org/api-guide/viewsets/#example

まず、TimelineSerializerに渡すオブジェクトタイプが必要です。 tweetsarticlesの2つの属性が必要です。

from collections import namedtuple

Timeline = namedtuple('Timeline', ('tweets', 'articles'))

次に、ツイートと記事をフェッチし、Timelineオブジェクトをインスタンス化し、TimelineSerializerデータを返すカスタムビューセットを定義します。

class TimelineViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing the Tweets and Articles in your Timeline.
    """
    def list(self, request):
        timeline = Timeline(
            tweets=Tweet.objects.all(),
            articles=Article.objects.all(),
        )
        serializer = TimelineSerializer(timeline)
        return Response(serializer.data)
29
Anentropic

複数のモデルをシリアル化して、各シリアル化モデルからフィルター処理された出力をフェッチし、単一のAPIから使用するという同じ状況がありました。私はこの結果を達成するために このモジュール に出くわしました。

1
Asif Khan