Djangoでtastypieを使ってREST APIを作る際に、bpmappersをどうやって組み合わせればよいか調べてた。
tastypieのCookbookのページにカスタムの値を追加する例がある。
Adding Custom Values
tastypieのソースコードを読んだところ、dehydrateメソッドで値の変換をするので良さそうに見えたので、ここにマッピング処理を挿し込む。
Django1.5.4, tastypie0.10.0。
試したコード
myapp/models.py
from django.db import models class Item(models.Model): name = models.CharField(max_length=20) price = models.PositiveIntegerField()
myapp/mappers.py
idをitem_idに、nameをitem_nameにマッピングする。
resource_uriというフィールドがtastypieのほうで追加されているので、そのまま使う。
from bpmappers import Mapper, RawField class ResouceMapper(Mapper): resource_uri = RawField() class ItemMapper(ResouceMapper): item_id = RawField('id') item_name = RawField('name')
myapp/resources.py
# coding: utf-8 from tastypie.resources import ModelResource from myapp.models import Item from myapp.mappers import ItemMapper class ItemResource(ModelResource): def dehydrate(self, bundle): # Bundleオブジェクトのdata辞書をbpmappersでマッピングする # モデルのフィールドとresource_uriという名前のキーがbundle.dataに入ってる # ここでrequestオブジェクトを使いたい場合はbundle.requestを参照すればよい bundle.data = ItemMapper(bundle.data).as_dict() return bundle class Meta: queryset = Item.objects.all() allowed_methods = ['get']
myproject/urls.py
urlsはtastypieのQuick Startほぼそのまま。
from django.conf.urls import patterns, include, url from tastypie.api import Api from myapp.resources import ItemResource v1_api = Api(api_name='v1') v1_api.register(ItemResource()) urlpatterns = patterns('', url(r'^api/', include(v1_api.urls)), )
実行結果
syncdbを実行して、適当にデータをshellで作って、runserverを起動。
Chromeで http://localhost:8000/api/v1/item/?format=json にアクセスしてJSON Viewで見た結果がこれ。
プロジェクト全体のソースコードはbitbucketに置いてます。
tokibito / sample_nullpobug / source / django / tastypie_bpmappers / myproject — Bitbucket