1. ホーム
  2. python

[解決済み] DjangoのRestフレームワークでレスポンスに仲介(モデル経由)を含める。

2022-06-19 15:28:47

質問

django rest フレームワークで m2m / through モデルとそのプレゼンテーションの扱いについて質問があります。古典的な例を見てみましょう。

models.py:

from django.db import models

class Member(models.Model):
    name = models.CharField(max_length = 20)
    groups = models.ManyToManyField('Group', through = 'Membership')

class Group(models.Model):
    name = models.CharField(max_length = 20)

class Membership(models.Model):
    member = models.ForeignKey('Member')
    group = models.ForeignKey('Group')
    join_date = models.DateTimeField()

serializers.pyを使用します。

imports...

class MemberSerializer(ModelSerializer):
    class Meta:
        model = Member

class GroupSerializer(ModelSerializer):
    class Meta:
        model = Group

views.pyを使用します。

imports...

class MemberViewSet(ModelViewSet):
    queryset = Member.objects.all()
    serializer_class = MemberSerializer

class GroupViewSet(ModelViewSet):
    queryset = Group.objects.all()
    serializer_class = GroupSerializer

MemberのインスタンスをGETすると、メンバーのすべてのフィールドとそのグループを正常に受け取ります。しかし、グループの詳細のみを取得し、Membershipモデルから来る余分な詳細は取得しません。

言い換えると、私は を期待します。 を受け取ることです。

{
   'id' : 2,
   'name' : 'some member',
   'groups' : [
      {
         'id' : 55,
         'name' : 'group 1'
         'join_date' : 34151564
      },
      {
         'id' : 56,
         'name' : 'group 2'
         'join_date' : 11200299
      }
   ]
}

注意点として join_date .

私は非常に多くの解決策を試しましたが、その中にはもちろん Django Rest-Framework の公式ページです。 を含め、多くの解決策を試しましたが、誰もそれについて適切な答えを与えていないようです - これらの追加フィールドを含めるにはどうすればいいのでしょうか?私は django-tastypie を使ってもっと簡単な方法を見つけましたが、他の問題もあり、 rest-framework の方が好きです。

どのように解決するのですか?

どうすれば......。

MemberSerializerに、以下のようなフィールドを定義します。

groups = MembershipSerializer(source='membership_set', many=True)

で、メンバーシップ・シリアライザーでは、このように作成することができます。

class MembershipSerializer(serializers.HyperlinkedModelSerializer):

    id = serializers.Field(source='group.id')
    name = serializers.Field(source='group.name')

    class Meta:
        model = Membership

        fields = ('id', 'name', 'join_date', )

これは、全体的な効果として、必要なメンバーシップをソースとするシリアライズされた値、groupsを作成し、カスタムシリアライザーを使用して表示したいビットを取り出します。

EDIT: @bryanph によってコメントされたように。 serializers.field にリネームされました。 serializers.ReadOnlyField に変更されました。

class MembershipSerializer(serializers.HyperlinkedModelSerializer):

    id = serializers.ReadOnlyField(source='group.id')
    name = serializers.ReadOnlyField(source='group.name')

    class Meta:
        model = Membership

        fields = ('id', 'name', 'join_date', )

最新の実装の場合