web-dev-qa-db-ja.com

djangoでRESTFUL APIからデータを消費する適切な方法

私はDjangoを学ぼうとしているので、現在のソリューションを持っている間、それがDjangoのベストプラクティスに従っているかどうかはわかりません。 APIのURLが次のようになっているとしましょう:

http://api.example.com/books?author=edwards&year=2009

Thsisは、2009年に書かれたEdwardsの書籍のリストを返します。次の形式で返されます。

{'results':
             [
                {
                   'title':'Book 1',
                   'Author':'Edwards Man',
                   'Year':2009
                },
                {
                   'title':'Book 2',
                   'Author':'Edwards Man',
                   'Year':2009}
           ]
}

現在、次のようにビューファイルでAPIを使用しています。

class BooksPage(generic.TemplateView):
    def get(self,request):
        r = requests.get('http://api.example.com/books?author=edwards&year=2009')
        books = r.json()
        books_list = {'books':books['results']}
        return render(request,'books.html',books_list)

通常、models.pyファイルでデータベースからデータを取得しますが、models.pyまたはviews.pyでこのAPIデータを取得する必要があるかどうかはわかりません。 models.pyにある場合、誰かがこれを行う方法の例を提供できますか?上記の例をスタックオーバーフローについて個別に書いたので、バグは純粋にここに書いた結果です。

47
user2694306

そのようなロジックを別のサービスレイヤー(services.py)に配置するアプローチが好きです。レンダリングするデータは、Django ORMの意味での「モデル」ではなく、単なる「表示」ロジック以上のものです。クリーンなカプセル化により、インターフェースの制御などを行うことができます。バッキングサービス(Python APIとパラメーター付きURL)のように見えるようにする)、@ sobolevnが述べたように、キャッシングなどの拡張機能を追加し、APIを単独でテストするなど。

簡単なservices.py、次のようになります。

def get_books(year, author):
    url = 'http://api.example.com/books' 
    params = {'year': year, 'author': author}
    r = requests.get(url, params=params)
    books = r.json()
    books_list = {'books':books['results']}
    return books_list

パラメータがどのように渡されるかに注意してください(requestsパッケージの機能を使用)。

その後、views.py

import services
class BooksPage(generic.TemplateView):
    def get(self,request):
        books_list = services.get_books('2009', 'edwards')
        return render(request,'books.html',books_list)

こちらもご覧ください:

102
bimsapi

.jsonの代わりにシリアライザーを使用します。これにより、多くの形式で柔軟に戻ることができます。rest-apiを使用する場合は、提供されたシリアライザーを使用することをお勧めします。

また、データ処理を維持し、view.pyでデータ要求を取得します。フォームは、ビジネスロジックとしてではなく、テンプレート化に使用されます。

3
Prateek099

さて、心に留めておくべきことがいくつかあります。まず、この場合、データはそれほど頻繁に変更されません。そのため、このような応答をキャッシュすることをお勧めします。多くのキャッシュツールがありますが、 redis は一般的なオプションです。または、キャッシュのためだけに追加のNoSQLデータベースを選択できます。

第二に、このデータを表示する目的は何ですか?ユーザーが本や著者などとやり取りすることを期待していますか?それが単なる情報である場合、フォームとモデルに必要はありません。そうでない場合は、書籍と著者の両方に適切なビュー、フォーム、モデルなどを提供する必要があります。

また、APIリクエストを呼び出す場所を考えると、2番目の質問に大きく依存していると思います。選択肢は次のとおりです。

  • views.pyデータを表示するだけです。
  • forms.pyまたはまだviews.py無活動。
1
sobolevn