次のモデルがあるとしましょう:
class Classroom(models.Model):
room_number = [....]
class Teacher(models.Model):
name = [...]
tenure = [...]
classroom = models.ForeignKey(Classroom)
ManyRelatedPrimaryKeyField関数ごとにこのような結果を取得する代わりに、
{
"room_number": "42",
"teachers": [
27,
24,
7
]
},
次のような完全な関連モデル表現を含むものを返します:
{
"room_number": "42",
"teachers": [
{
'id':'27,
'name':'John',
'tenure':True
},
{
'id':'24,
'name':'Sally',
'tenure':False
},
]
},
これは可能ですか?もしそうなら、どのように?そして、これは悪い考えですか?
最も簡単な方法は、 深度引数 を使用することです
class ClassroomSerializer(serializers.ModelSerializer):
class Meta:
model = Classroom
depth = 1
ただし、これには前方関係の関係のみが含まれます。この場合、教師フィールドは逆関係であるため、必要なものではありません。
より複雑な要件がある場合(たとえば、逆の関係を含める、一部のフィールドをネストし、他のフィールドはネストしない、またはフィールドの特定のサブセットのみをネストする)、 nesterizers など、次のことができます。
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set')
class Meta:
model = Classroom
シリアライザーフィールドでsource引数を使用して、フィールドのソースとして使用する属性を指定することに注意してください。 source
モデルで related_name オプションを使用して、代わりにteachers
属性が存在することを確認することで、Teacher
引数を削除できます。 classroom = models.ForeignKey(Classroom, related_name='teachers')
覚えておくべきことの1つは、ネストされたシリアライザーは現在、書き込み操作をサポートしていないことです。書き込み可能な表現の場合、pkやハイパーリンクなどの通常のフラットな表現を使用する必要があります。
@TomChristieありがとうございます!!!あなたは私をたくさん助けてくれました!私はそれを少し更新したいと思います(私が遭遇した間違いのため)
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set', many=True)
class Meta:
model = Classroom
field = ("teachers",)
これは drf-flex-fields と呼ばれる非常に便利なダンディDjangoパッケージを使用することでも実現できます。私たちはそれを使用し、それはかなり素晴らしいです。 pip install drf-flex-fields
をインストールし、シリアライザーに渡して、expandable_fields
とビンゴを追加します(下の例を参照)。また、ドット表記を使用して、深いネスト関係を指定できます。
from rest_flex_fields import FlexFieldsModelSerializer
class ClassroomSerializer(FlexFieldsModelSerializer):
class Meta:
model = Model
fields = ("teacher_set",)
expandable_fields = {"teacher_set": (TeacherSerializer, {"source": "teacher_set"})}
次に、?expand=teacher_set
をURLに追加すると、拡張された応答が返されます。これがいつか誰かを助けることを願っています。乾杯!