課題
- django-rest-framework を使ったWeb APIのドキュメントを、drf-yasgで生成しようとしたところ、modelで
ForeignKey
として定義していたパラメータの情報が正しく表示されなかった
環境
- python3.6.5
- djangorestframework==3.9.1
- drf-yasg==1.13.0
サンプルコード
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=100, blank=True, null=True)
contents_text = models.TextField(blank=True, null=True)
pubdate = models.DateTimeField(auto_now_add=True)
class User(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
class Comment(models.Model):
target_article = models.ForeignKey(Article, on_delete=models.SET_NULL, null=True, related_name='comments')
comment = models.TextField(blank=True, null=True)
pubdate = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
from rest_framework.serializers import ModelSerializer
from .models import Article, Comment, User
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = '__all__'
class CommentSerializer(ModelSerializer):
class Meta:
model = Comment
fields = [
'id',
'target_article',
'comment',
'pubdate',
'user',
]
class ArticleSerializer(ModelSerializer):
class Meta:
model = Article
fields = [
'id',
'title',
'contents_text',
'pubdate',
'comments',
]
- redocの出力
解決方法
-
ArticleSerializer
のcomments
フィールドをSerializerMethodField
として定義し、get_comments
でArticle
に紐づくComment
を取得する -
CommentSerializer
のuser
フィールドをSerializerMethodField
として定義し、get_user
メソッドでComment
に紐づくUser
を取得する -
get_comments
メソッドとget_user
メソッドに@swagger_serializer_method
デコレータを付加し、それぞれのメソッド内で使うSerializerを指定する
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from .models import Article, Comment, User
from drf_yasg.utils import swagger_serializer_method
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = '__all__'
class CommentSerializer(ModelSerializer):
user = SerializerMethodField()
class Meta:
model = Comment
fields = [
'id',
'target_article',
'comment',
'pubdate',
'user',
]
@swagger_serializer_method(serializer_or_field=UserSerializer)
def get_user(self, instance):
return UserSerializer(instance.user).data
class ArticleSerializer(ModelSerializer):
comments = SerializerMethodField()
class Meta:
model = Article
fields = [
'id',
'title',
'contents_text',
'pubdate',
'comments',
]
@swagger_serializer_method(serializer_or_field=CommentSerializer)
def get_comments(self, instance):
try:
return CommentSerializer(instance.comments.get(target_article=instance)).data
except Exception as e:
print(e)
return None
- redocの出力
補足
swagger_serializer_method
デコレータをつけないとForeignKey
で取得しようとしているフィールドはstring
型として認識される