DRFは初めてで、APIの構築を開始したばかりです。私は2つのモデルを持っています。子モデルは、外部キーで親モデルに接続されています。ここに私が持っているモデルの簡略版があります:
class Parent(models.Model):
name = models.CharField(max_length=50)
class Child(models.Model):
parent = models.ForeignKey(Parent)
child_name = models.CharField(max_length=80)
シリアライザーを作成するために、私は DRF Serializer Relations に従い、次のように作成しました。
class ChildSerializer(serializers.HyperlinkedModelSerializer):
parent_id = serializers.PrimaryKeyRelatedField(queryset=Parent.objects.all(),source='parent.id')
class Meta:
model = Child
fields = ('url','id','child_name','parent_id')
def create(self, validated_data):
subject = Child.objects.create(parent=validated_data['parent']['id'], child_name=validated_data['child_name'])
return child
class ParentSerializer(serializers.HyperlinkedModelSerializer):
children = ChildSerializer(many=True, read_only=True)
class Meta:
model = Course
fields = ('url','id','name','children')
親のシリアライザのすべての子のリストを取得しようとしています。私が欲しいのはこのような応答を得ることができることです:
{
'url': 'https://dummyapidomain.com/parents/1/',
'id': '1',
'name': 'Dummy Parent Name',
'cildren': [
{'id': 1, 'child_name': 'Dummy Children I'},
{'id': 2, 'child_name': 'Dummy Children II'},
{'id': 3, 'child_name': 'Dummy Children III'},
...
],
}
ParentモデルにはParentとChildの間にリンクがないため、これが機能するとは期待していませんでした ただし、ドキュメントで推奨される方法です 。機能しませんでした。
次のエラーメッセージが表示されます。
Got AttributeError when attempting to get a value for field `children` on serializer `ParentSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Parent` instance.
Original exception text was: 'Parent' object has no attribute 'children'.
それは完全に合理的だと思いますが、ここで何が欠けているのか理解できませんでした。
親のシリアライザのすべての子のリストを取得するにはどうすればよいですか?
あなたの問題は、子供モデルにrelated_nameを追加するのを忘れていることだと思います。私はこのようなモデルを持っているでしょう:
class Parent(models.Model):
name = models.CharField(max_length=50)
class Child(models.Model):
parent = models.ForeignKey(Parent, related_name='children') # <--- Add related_name
child_name = models.CharField(max_length=80)
そして、私はこの変更であなたが得るエラーを解決すると思います
これは2つの方法で実装できます。
SerializerMethodField
を使用すると、コードは次のようになります。
class ParentSerializer(serializers.ModelSerializer):
children_list = serializers.SerializerMethodField('_get_children')
def _get_children(self, obj):
serializer = ChildSerializer(obj.child_list(), many=True)
return serializer.data
class Meta:
model = Course
fields = ('url','id','name','children_list')
すべてのフィールドはモデルまたはメソッドの属性である可能性があるため、Parent
モデルでget_children_listメソッドを定義し、ParentSerializer
のフィールドのリストで呼び出すことができます。
class ParentSerializer(serializers.ModelSerializer):
class Meta:
model = Course
fields = ('url','id','name','get_children_list')
注:このシナリオでは、serializers.ModelSerializer
から継承する必要があります