2012-11-28 10 views
124

私はDjango RESTフレームワークの初心者であり、あなたの助言が必要です。私はWebサービスを開発しています。サービスは、他のサービスにRESTインタフェースを提供する必要があります。私が実装する必要があるRESTインターフェースは、私のモデルで直接動作していません(get、put、post、delete操作を意味します)。代わりに、いくつかの計算結果を他のサービスに提供します。要求に応じて、私のサービスはいくつかの計算を行い、結果を返すだけです(結果は独自のデータベースに保存されません)。Django RESTフレームワーク:非モデルシリアライザ

以下は、RESTインターフェイスを実装する方法を私が理解したものです。私が間違っているなら、私を訂正してください。

  1. 計算を行うクラスを作成します。名前を 'CalcClass'とします。 CalcClassはそのモデルをその作業に使用します。
    • 計算に必要なパラメータはコンストラクタに渡されます。
    • calc演算を実装します。 ResultClassとして結果を返します。
  2. 結果クラスを作成します。
    • オブジェクトから派生したものです。
    • これは、calcの結果を含む属性しか持っていません。
    • 計算結果の一部は、タプルのタプルとして表されます。私が理解するように、それ以上のシリアライゼーションでは、それらの結果に対して別のクラスを実装し、そのようなオブジェクトのリストをResultClassに追加する方がよいでしょう。
  3. ResultClassのシリアライザを作成します。
    • シリアライザから派生します。
    • 計算結果は読み取り専用です。したがって、IntegerFieldなどの特殊なクラスではなく、フィールドのほとんどがフィールドクラスを使用します。
    • 私は結果を格納するつもりはないので(私はちょうど要求に応じて返したい)、ResultClassとSerializerのどちらにもsave()メソッドを含めるべきではありません。
    • ネストされた結果のImplシリアライザ(上記のタプルのタプルを覚えておいてください)。
  4. 計算結果を返すには、ビューを作成します。
    • APIViewから派生します。
    • get()が必要です。
    • get()リクエストから取得したparamsでCalcClassを作成し、calc()を呼び出してResultClassを取得し、シリアライザを作成してResultClassを渡し、Response(serializer.data)を返します。
  5. のURL
    • 私の場合には、APIのルートがありません。私はさまざまな計算結果(diffパラメータを持つcalc)を得るためのURLを用意してください。
    • apiの閲覧にformat_suffix_patternsを呼び出します。

私は何かを見逃しましたか?アプローチは一般的に正しいですか?

答えて

131

Django-rest-frameworkは、モデルに結び付けなくてもうまく動作します。あなたのアプローチは大丈夫だと思いますが、私はあなたがすべての作業をするためのいくつかのステップをトリミングできると信じています。

たとえば、restフレームワークにはいくつかの組み込みレンダラーが付属しています。ボックスの外でJSONとXMLをAPIコンシューマに返すことができます。必要なPythonモジュールをインストールするだけでYAMLを有効にすることもできます。 Django-rest-frameworkは、dict、list、tupleのような基本オブジェクトを出力します。

基本的に、引数を取り込む関数またはクラスを作成するだけで、必要な計算がすべて実行され、結果がタプルでREST APIビューに返されます。 JSONやXMLがあなたのニーズに合っていれば、django-rest-frameworkがあなたのためにシリアライゼーションを行います。

この場合、手順2と3をスキップして、計算に1つのクラスを使用し、APIコンシューマーにプレゼンテーションに1つだけ使用できます。ここで

が抜粋されているあなたを助けることがあります。

を私はこれをテストしていませんのでご注意ください。これは、例としてのみのものだが、それは動作するはずです:)

CalcClass:

class CalcClass(object): 

    def __init__(self, *args, **kw): 
     # Initialize any variables you need from the input you get 
     pass 

    def do_work(self): 
     # Do some calculations here 
     # returns a tuple ((1,2,3,), (4,5,6,)) 
     result = ((1,2,3,), (4,5,6,)) # final result 
     return result 

RESTビュー:

from rest_framework.views import APIView 
from rest_framework.response import Response 
from rest_framework import status 

from MyProject.MyApp import CalcClass 


class MyRESTView(APIView): 

    def get(self, request, *args, **kw): 
     # Process any get params that you may need 
     # If you don't need to process get params, 
     # you can skip this part 
     get_arg1 = request.GET.get('arg1', None) 
     get_arg2 = request.GET.get('arg2', None) 

     # Any URL parameters get passed in **kw 
     myClass = CalcClass(get_arg1, get_arg2, *args, **kw) 
     result = myClass.do_work() 
     response = Response(result, status=status.HTTP_200_OK) 
     return response 

あなたのurls.py:

from MyProject.MyApp.views import MyRESTView 
from django.conf.urls.defaults import * 

urlpatterns = patterns('', 
    # this URL passes resource_id in **kw to MyRESTView 
    url(r'^api/v1.0/resource/(?P<resource_id>\d+)[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'), 
    url(r'^api/v1.0/resource[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'), 
) 

http://example.com/api/v1.0/resource/?format=jsonにアクセスすると、このコードはリストのリストを出力するはずです。接尾辞を使用する場合は、​​を.jsonに置き換えることができます。ヘッダーに"Content-type"または"Accept"を追加して、戻したいエンコードを指定することもできます。

[ 
    [ 
    1, 
    2, 
    3 
    ], 
    [ 
    4, 
    5, 
    6 
    ] 
] 

希望すると、これが役に立ちます。

+1

こんにちはガブリエル!あなたの答えをありがとう!私はすでに私の計画に従って必要なものを実装しました。正常に動作します!私はより良いjson出力のためにシリアライザを使用しました。 – Zakhar

+2

ありがとう、私の一日を救った。それはドキュメンテーションの一部でなければなりません。 – neelix

+3

私はこの提案に従おうとしましたが、次のように表示されます。 "DjangoModelPermissionsを' .model'または '.queryset'プロパティを持たないビューに適用することはできません。"私は提供された正確な例を試しました。 django-rest-frameworkの最近のバージョンでは何かになりますか? – Orlando

関連する問題