AngularJS1 + Django REST Frameworkに再挑戦 その7 Comment Create API Endpoint & Serializer Context
概要
AngularJS1 + Django REST Frameworkに再挑戦 その7 Comment Create API Endpoint & Serializer Context
参考動画
Django + AngularJS | Coding For Entrepreneurs
Comment Create API Endpoint & Serializer Context
http://127.0.0.1:8000/api/comments/create/
にアクセスして、apiを作成しようとしても、valid errorが表示されて、作成できない。なので、serializerを変更する。comments/api/serializers.pyの、
class CommentCreateSerializer(ModelSerializer):
をコピペして独立させる。以下のように追記する。
from rest_framework import serializers ... class CommentCreateSerializer(ModelSerializer): type = serializers.CharField(write_only=True) #Post slug = serializers.SlugField(write_only=True) #new-title parent_id = serializers.IntergerField(required=False) # comment自体が親になる可能性もあるため ...
def __init__
の初期化メソッドの箇所は丸々削除する。class Meta
のfieldsを追記する。後、validate以下は一旦コメントアウトする。
fields = [ 'id', 'content', 'type', 'slug', 'parent_id', 'timestamp', ]
まあ普通のserializerに戻したという感じで、ここから新たにserializerの機能を追加していく。
def validate
を以下のように修正する。
def validate(self, data): model_type = data.get("type", "post") model_qs = ContentType.objects.filter(model=model_type) if not model_qs.exists() or model_qs.count() != 1: raise ValidationError("This is not a valid content type") SomeModel = model_qs.first().model_class() slug = data.get("slug") obj_qs = SomeModel.objects.filter(slug=slug) if not obj_qs.exists() or obj_qs.count() != 1: raise ValidationError("This is not a slug for this content type") parent_id = data.get("parent_id") if parent_id: parent_qs = Comment.objects.filter(id=parent_id) if not parent_qs.exists() or parent_qs.count() != 1: raise ValidationError("This is not a valid parent for this content") return data
- def createも同じように、validated_dataを利用して、書き換える。
def create(self, validated_data): content = validated_data.get("content") if user: main_user = user else: main_user = User.objects.all().first() model_type = validated_data.get("type", "post") slug = validated_data.get("slug") parent_id = validated_data.get("parent_id") parent_obj = None if parent_id: parent_obj = Comment.objects.filter(id=parent_id).first() comment = Comment.objects.create_by_model_type( model_type, slug, content, main_user, parent_obj=parent_obj, ) return comment
- comments/api/views.pyのCommentCreateAPIViewを修正する。一旦シンプルな形に戻す。
class CommentCreateAPIView(CreateAPIView): queryset = Comment.objects.all() serializer_class = CommentCreateSerializer
- CommentCreateAPIViewに、contextを追記する。(get_serializer_contextを上書きする)
class CommentCreateAPIView(CreateAPIView): queryset = Comment.objects.all() serializer_class = CommentCreateSerializer def get_serializer_context(self): context = super().get_serializer_context() context['user'] = self.request.user return context
- なぜ、userをわざわざcontextで渡すかというと、CommentCreateSerializerの方で、使いたいらしい。
def create(self, validated_data): content = validated_data.get("content") model_type = validated_data.get("type", "post") slug = validated_data.get("slug") parent_id = validated_data.get("parent_id") parent_obj = None if parent_id: parent_obj = Comment.objects.filter(id=parent_id).first() user = self.context['user'] comment = Comment.objects.create_by_model_type( model_type, slug, content, user, parent_obj=parent_obj, ) return comment
- ここまでセットしたら、
http://127.0.0.1:8000/api/comments/create/
でコメントを作成してみる。。。。無事表示された〜!