Django restフレームワークでのモデルとそのプレゼンテーションを介したm2m /の取り扱いについて質問があります。古典的な例を見てみましょう。
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
メンバーのインスタンスを取得すると、メンバーのすべてのフィールドとそのグループを正常に受け取りますが、メンバーシップモデルからの追加の詳細なしで、グループの詳細のみを取得します。
言い換えれば、Iexpectを受信する:
{
'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 official page about it を含む非常に多くのソリューションを試してみましたが、誰もそれについて適切な明白な答えを出していないようです-これらの追加フィールドを含めるために何をする必要がありますか? Django-tastypieの方がわかりやすいのですが、他にもいくつか問題があり、レストフレームワークを好みます。
どうでしょう.....
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', )
これは、必要なメンバーシップをソースとして持つシリアル化された値、グループを作成し、カスタムシリアライザーを使用して表示するビットを引き出します。
編集:@bryanphのコメント通り、serializers.field
はDRF 3.0で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', )
最新の実装向け
私はこの問題に直面しており、私のソリューション(DRF 3.6を使用)は、オブジェクトでSerializerMethodFieldを使用し、Membershipテーブルを次のように明示的にクエリすることでした。
class MembershipSerializer(serializers.ModelSerializer):
"""Used as a nested serializer by MemberSerializer"""
class Meta:
model = Membership
fields = ('id','group','join_date')
class MemberSerializer(serializers.ModelSerializer):
groups = serializers.SerializerMethodField()
class Meta:
model = Member
fields = ('id','name','groups')
def get_groups(self, obj):
"obj is a Member instance. Returns list of dicts"""
qset = Membership.objects.filter(member=obj)
return [MembershipSerializer(m).data for m in qset]
これにより、各ディクショナリがMembershipSerializerからシリアル化されるグループキーのディクテーションのリストが返されます。書き込み可能にするには、MemberSerializer内で独自の作成/更新メソッドを定義して、入力データを反復処理し、メンバーシップモデルインスタンスを明示的に作成または更新できます。