DjangoのモデルにTextFieldでJSON文字列を保存しておき、APIをDjango REST Frameworkで提供する例。
JSONデータを保存して、読み込み時にもJSON形式のまま提供したかった。
restframeworkのシリアライザのFieldクラスを継承し、JSONを扱うフィールドを定義して使う。
コード
app1/models.py:
from django.db import models class Model1(models.Model): class Meta: ordering = ['pk'] data = models.TextField("JSONデータ", null=True, blank=True)
app1/serializers.py:
import json from rest_framework import serializers from .models import Model1 class JSONDataField(serializers.Field): """JSONテキストのシリアライザ,デシリアライザフィールド """ def to_representation(self, obj): if obj: return json.loads(obj) return None def to_internal_value(self, data): return json.dumps(data, indent=2) class Model1Serializer(serializers.ModelSerializer): data = JSONDataField() class Meta: model = Model1 fields = [ 'id', 'data' ]
app1/views.py:
import coreapi import coreschema from rest_framework import viewsets from rest_framework.schemas import AutoSchema from .serializers import Model1Serializer from .models import Model1 class Model1Schema(AutoSchema): def get_manual_fields(self, path, method): # 作成, 更新だけdataフィールドの定義を差し込む if method not in ['POST', 'PUT', 'PATCH']: return [] return [ coreapi.Field( "data", required=False, location="form", schema=coreschema.Object() ) ] class Model1ViewSet(viewsets.ModelViewSet): serializer_class = Model1Serializer queryset = Model1.objects.all() schema = Model1Schema()
REST Frameworkで自動生成されるAPIドキュメントで扱えるように、schema定義を入れています。
app1/urls.py:
from django.urls import path from rest_framework.documentation import include_docs_urls from rest_framework.routers import DefaultRouter from . import views router = DefaultRouter() router.register(r'model1', views.Model1ViewSet, base_name='model1') urlpatterns = [ path('docs/', include_docs_urls(title='app1 API', public=True)), ] + router.urls
動作例
list:
create: