読者です 読者をやめる 読者になる 読者になる

Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django REST Frameworkに再挑戦 その13 Comment Create Serializer Function Part 1

概要

Django REST Frameworkに再挑戦 その13 Comment Create Serializer Function Part 1

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

Comment Create Serializer Function Part 1

  • 先ずは、comments/api/serializers.pyにコードを追記する。ここでは、あとで、post/api/serializers.py から、このcreate serializerを呼び出したいので、functionとして、create_comment_serializerを定義する。
def create_comment_serializer(model_type='post', slug=None, parent_id=None) # slugの箇所は、object_idでも可。
    class CommentCreateSerializer(ModelSerializer):
        class Meta:
            model = Comment
            fields = [
                'id',
                'parent',
                'content',
                'timestamp',
            ]

        # modelserializerの初期化メソッドを上書きする。
        # インスタンス変数の設定
        def __init__(self, *args, **kwargs):
            self.model_type = model_type # 引数を代入
            self.slug = slug # 引数を代入
            self.parent_obj = None # 初期化
            if self.parent_id:
                parent_qs = Comment.objects.filter(id=parent_id) # parent_idで絞り込み
                if parent_qs.exists() and parent_qs.count() == 1: # 絞り込んで、存在する場合
                    self.parent_obj = parent_qs.first()
            return super(CommentCreateSerializer, self).__init__(*args, **kwargs)
                    
    return CommentCreateSerializer
  • validateメソッドを定義していく。ここは結構高度なことをしている気がする。content types フレームワークという手法を使っている。

contenttypes フレームワーク — Django v1.0 documentation

from django.contrib.contenttypes.models import ContentType
...
def create_comment_serializer(model_type='post', slug=None, parent_id=None): # slugの箇所は、object_idでも可。
    class CommentCreateSerializer(ModelSerializer):
        class Meta:
            model = Comment
            fields = [
                'id',
                'parent',
                'content',
                'timestamp',
            ]

        def __init__(self, *args, **kwargs):
            self.model_type = model_type
            self.slug = slug
            self.parent_obj = None
            if self.parent_id:
                parent_qs = Comment.objects.filter(id=parent_id)
                if parent_qs.exists() and parent_qs.count() == 1:
                    self.parent_obj = parent_qs.first()
            return super(CommentCreateSerializer, self).__init__(*args, **kwargs)

        def validate(self, data):
            model_type = self.model_type #__init__で初期化されたmodeltypeを代入する。
            model_qs = ContentType.objects.filter(model=model_type) # content_typeのvalidationを行う
            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() # model_class
            obj_qs = SomeModel.objects.filter(slug=self.slug)
            if not obj_qs.exists() or obj_qs.count() != 1:
                raise ValidationError("This is not a slug for this content_type")
            return data

    return CommentCreateSerializer