0
Django 1.5 における効果的な MTV 設計 & ネイティブApp
@luyikei
自己紹介
● @luyikei
●
Linux Mint, Qt, Django が好きです
内容
1, DjangoでMTVデザインパターンを最も有効に活用するには
 Model : 1, Model Relationships
2, Mata Options
 Template : 1, Python Template Engine...
内容
2,ネイティブアプリケーションとの連携
 API の実装
 OAuth の実装
 クライアント側の処理 (PyQt 使用)
 
MTV デザインパターンを最も有効に活用するには
MTV とは
Django appears to be a MVC
framework, but you call the
Controller the “view”, and the
View the “template”. How come...
なぜ MVC じゃなく MTV なの?
さらに、テンプレートによってコンテンツとプレゼンテーションの分離がはっ
きり しています。Django では、ビューはどのデータを提示するかを決めてい
ますが、 ビューは通常、 どのように データを提示す...
つまり MVC とは少し違ったデザインパターンで
ある
ということである
Model : 1, Model Relationships
簡易 商品管理 サイトを構築する。
- モデルは 「サンドイッチ, おにぎり」
- 一括で管理したい場合はどうするか
Model - サンドイッチ
Title : “シャキシャキレタス”
Price : 220
Vegetable : “Lettuce”
Meat : “Ham”
OnEgg : True
Model - おにぎり
Title : “手巻おにぎり 紅しゃけ”
Price : 136
Guzai : “Salmon”
モデルの継承を使用
class Item(models.Model):
title = models.CharField(max_length=200)
price = models.IntegerField()
Model “サンドイッチ”を定義
class Sandwich(Item):
vegetable = models.CharField(max_length=200)
meat = models.CharField(max_length=20...
Model “おにぎり” を定義
class Onigiri(Item):
Guzai = models.CharField(max_length=200)
Item の子モデルの取得
Onigiri の場合。
Item.onigiri
Sandwich の場合
Item.sandwich
子モデルは種類がわかっている時のみ取得でき
る!
子モデルを取得する方法
class Item(models.Model):
title = models.CharField(max_length=200)
price = models.IntegerField()
subclass =
mo...
子モデル取得関数
def as_child(self):
return getattr(self, self.subclass.lower())
例:
i=Item.objects.get(id=1)
child=i.as_child()
どう動くか見てみましょう
Model : 2, Mata Options
Django のモデルの情報を取得するのに
Meta オプションは重宝します
Django Models Internals Documentation
https://django-model-_meta-
reference.readthedocs.org/en/latest/index.html
get_all_related_objects_with_model
Returns a list of (related-object, model) pairs. Similar to
get_fields_with_model().
Re...
get_parent_list
Returns a list of all the ancestor of this model as a list. Useful for
determining if something is an ance...
get_latest_by
model Manager の latest() , earliest() メソッドで返さ
れるオブジェクトの判断基準を設定
例:
get_latest_by = "order_date"
ordering
オブジェクトのリストを取得するときに使われ
る、オブジェクトのデフォルトの並び順規則を設
定
例:
ordering = ['-order_date']
db_table
モデルの使うデータベーステーブルの名前
例:
db_table = 'music_album'
Template : 1, Python Template Engine
・Django Template
・Jinja2
・Mako
・Chameleon
Django Template
・Django 標準のテンプレートエンジン
・Django のテンプレート言語は、釣合いの取れたパワーと簡便さを実現するように、 また HTML を扱い
なれた人にとっては快適になるように設計されています。 Sm...
簡潔で可読性の高いコード
Test[“a”] → {{ Test.a }}
Test[“a”][“b”] → {{ Test.a.b }}
Test[a].b() → {{ Test.a.b }}
Test.a.b → {{ Test.a.b ...
Jinja 2
・Django Template のパワーアップ版
・書式はほぼ同じなので移植しやすい
・高速
・おすすめ!
Django Template との比較
・Method Calls
例: a.b() → {{ a.b() }} (必ず)
a[“b”] → {{ a[“b“] }} (任意)
・Conditions
例: {% ifequal a b %}...
Mako
<%inherit file="base.html"/>
<%
rows = [[v for v in range(0,10)] for row in range(0,10)]
%>
<table>
% for row in rows...
Mako = 高機能
先ほどのコードを見てみると Django Template では
とてもではないが表現できるものではないことがわかる。
コードの可読性は Django より劣る傾向にあるだろう
しかし表現の幅は広がるだろう
正確で厳しいコード
Test[“a”] → ${ Test[“a”] }
Test[“a”][“b”] → ${ Test[“a”][“b”] }
Test[a].b() → ${ Test[a].b() }
Test.a.b → ${ Tes...
Chameleon
<html>
<meta>
<title tal:content="context.title" />
</meta>
<body>
<div tal:condition="items">
<p>These are your...
Chameleon TAL≒
・TAL とは Zope のテンプレートエンジン
・Chameleon はそれをベースに改良したテンプ
レートエンジン
・XMLベース
Django の XML ベーステンプレートエンジンに対する 評価
①
「それは、 Django のテンプレート言語を XML/HTML テンプレート
以外にも使いたいと考えているからです。 」
Django テンプレートエンジンについて
「W...
まず・・・
例:
polls/
models.py
templatetags/
__init__.py
poll_extras.py
views.py
カスタムテンプレートタグ・フィルターは Django アプリケーションのフォルダ内の tem...
Django の XML ベーステンプレートエンジンに対する 評価
②
そう、もう一つあります:
人間に XML を編集させるなんて、
サディスティック でしかありません!
http://docs.djangoproject.jp/ja/lat...
Template : 2, Custom tags and filters
今回は Django Template において説明します
django/template/defaultfilters.py
from django.template.base import Library
register = Library()
@register.filter(is_safe=T...
Django のソースを読むとわかる!
テンプレートのフィルターの書き方は
Python の 関数 の書き方と同じ!
まず・・・
例:
polls/
models.py
templatetags/
__init__.py
poll_extras.py
views.py
カスタムテンプレートタグ・フィルターは Django アプリケーションのフォルダ内の tem...
フィルターを登録
例:
from django.template.base import Library
register = Library()
@register.filter()
def nothing(value):
pass
フィルタ...
タグの場合も同じく
例:
from django.template.base import Library
register = Library()
@register.tag
def nothing(value):
pass
タグを登録し完了
View : 1, Sessions
セッションとは
ユーザがあるサイトを訪れてからそこを離れるまでの一連の
通信。
HTTP自体にはユーザを識別する機能が存在しないの
で、Cookieなどを使用して同一人物か否かを識別する。
たとえば、はてなにログインしてからログアウトするまでの...
変数の保存
例:
request.session[“Height”] = 120
変数の取得
例:
request.session.get('Height', 0):
get(key, default=None)
例: fav_color = request.session.get('fav_color', 'red')
変数の削除
例:
del request.session[“Height”]
簡単!
View : 2, Cookie
クッキーの保存
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/',
domain=None, secure=None, httponly=Fa...
クッキーの取得
例:
request.COOKIES.get('Height')
簡単!
View : 3, Cache
キャッシュとは
使用頻度の高いデータを高速な記憶装置に蓄えておくことに
より、いちいち低速な装置から読み出す無駄を省いて高速化
すること。また、その際に使われる高速な記憶装置や、複製
されたデータそのもののこと。
http://e-words....
キャッシュの設定
Memcached
データベースを使ったキャッシュ
データベースを使ったキャッシュと、マルチデータ
ベース
ファイルシステムを使ったキャッシュ
ローカルメモリ上のキャッシュ
ダミーキャッシュ (開発用)
例:Memcached
settings.py に
CACHES = {
'default': {
'BACKEND':
'django.core.cache.backends.memcached.MemcachedC
ache',
'LOCA...
サイト単位のキャッシュ
MIDDLEWARE_CLASSES = (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddle...
ビュー単位のキャッシュ
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
…
又は
from djan...
テンプレートの部分的キャッシュ
{% load cache %}
{% cache 500 sidebar %}
.. sidebar ..
{% endcache %}
http://docs.djangoproject.jp/en/late...
2,ネイティブアプリケーションとの
連携
ネイティブアプリケーション
ネイティブアプリケーションとの連携について
実際にはクライアントの作成に等しいが、
Django の ネイティブアプリケーション のクライ
アントの作成事例を中々見かけないのでこの題に
設定した。
Qt を使用し実装...
まずは OAuth の説明
OAuth とは・・・
・「OAuth (オー オース[1]) は、ブレイン・クックとクリス・メッ
シーナが始めたオープンプロトコルであり、デスクトップ、モバ
イル、WebアプリケーションなどにセキュアなAPI認可
...
詳しい説明
● http://www.atmarkit.co.jp/fsecurity/rensai/digid01/02.htm
準備
●
Django の OAuth2 実装に
django-oauth-plus を使用。
●
Django の API 実装に
django-tastypie を使用。
INSTALLED_APPS に以下を追記
INSTALLED_APPS = (
'tastypie',
'oauth_provider',
)
まずは API を実装
common/api.py
from tastypie.resources import ModelResource
from common.models import Onigiri
class OnigiriReso...
Urlsの編集
ecsite/urls.py
from tastypie.api import Api
from django.contrib import admin
admin.autodiscover()
onigiri_resource...
完成!(例)
$ curl http://127.0.0.1:8000/api/v1/onigiri/?format=json
{"meta": {"limit": 20, "next": null, "offset": 0, "previou...
しかしこの状態では
However, if you try sending a POST/PUT/DELETE to the resource,
you find yourself getting “401 Unauthorized” erro...
認証・権限の実装
common/api.py
from tastypie.authentication import OAuthAuthentication
from tastypie.authorization import DjangoAu...
同じコマンドを実行
$ curl http ://127.0.0.1:8000/api/v1/onigiri/?format=json
Invalid request parameters.
OAuth実装完了!
検証: Consumer を作成
$ ./manage.py shell
>>> from oauth_provider.models import Consumer, Token
>>> c = Consumer()
>>> c.genera...
検証: Token を作成
$ ./manage.py shell
>>> from django.contrib.auth.models import User
>>> u = User.objects.all()[0]
>>> t = To...
ここでこのコマンドを実行
# coding=utf-8
import json
import requests
from oauth_hook import OAuthHook
consumer_key = 'b10945ea448344bb8...
結果は
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null,
"total_count": 1}, "objects": [{"guzai": "gre", "i...
PyQt で実装
おわり!
Upcoming SlideShare
Loading in...5
×

Django 1.5 における効果的な MTV 設計 & ネイティブApp

3,426

Published on

Django 1.5 における効果的な MTV 設計 & ネイティブApp @ PyCon APAC 2013

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,426
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
15
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "Django 1.5 における効果的な MTV 設計 & ネイティブApp"

  1. 1. Django 1.5 における効果的な MTV 設計 & ネイティブApp @luyikei
  2. 2. 自己紹介 ● @luyikei ● Linux Mint, Qt, Django が好きです
  3. 3. 内容 1, DjangoでMTVデザインパターンを最も有効に活用するには  Model : 1, Model Relationships 2, Mata Options  Template : 1, Python Template Engine 2, Custom tags and filters  View : 1, Sessions 2, Cookie 3, Cache    
  4. 4. 内容 2,ネイティブアプリケーションとの連携  API の実装  OAuth の実装  クライアント側の処理 (PyQt 使用)  
  5. 5. MTV デザインパターンを最も有効に活用するには
  6. 6. MTV とは Django appears to be a MVC framework, but you call the Controller the “view”, and the View the “template”. How come you don’t use the standard names?¶ (https://docs.djangoproject.com/en/dev/faq/general/ より)
  7. 7. なぜ MVC じゃなく MTV なの? さらに、テンプレートによってコンテンツとプレゼンテーションの分離がはっ きり しています。Django では、ビューはどのデータを提示するかを決めてい ますが、 ビューは通常、 どのように データを提示するかをテンプレートに委 ねます。 では、「コントローラ」はどこに入るのでしょうか。 Django の場合、おそら くフ レームワーク、すなわち URL 設定にしたがってリクエストを適切な ビューに送信す る機構自体がコントローラにあたるといえるでしょう。 ( http://www.djangoproject.jp/doc/ja/1.0/faq/general.html )
  8. 8. つまり MVC とは少し違ったデザインパターンで ある ということである
  9. 9. Model : 1, Model Relationships 簡易 商品管理 サイトを構築する。 - モデルは 「サンドイッチ, おにぎり」 - 一括で管理したい場合はどうするか
  10. 10. Model - サンドイッチ Title : “シャキシャキレタス” Price : 220 Vegetable : “Lettuce” Meat : “Ham” OnEgg : True
  11. 11. Model - おにぎり Title : “手巻おにぎり 紅しゃけ” Price : 136 Guzai : “Salmon”
  12. 12. モデルの継承を使用 class Item(models.Model): title = models.CharField(max_length=200) price = models.IntegerField()
  13. 13. Model “サンドイッチ”を定義 class Sandwich(Item): vegetable = models.CharField(max_length=200) meat = models.CharField(max_length=200) onEgg = models.BooleanField(default=False)
  14. 14. Model “おにぎり” を定義 class Onigiri(Item): Guzai = models.CharField(max_length=200)
  15. 15. Item の子モデルの取得 Onigiri の場合。 Item.onigiri Sandwich の場合 Item.sandwich
  16. 16. 子モデルは種類がわかっている時のみ取得でき る!
  17. 17. 子モデルを取得する方法 class Item(models.Model): title = models.CharField(max_length=200) price = models.IntegerField() subclass = models.CharField(max_length=200,editable=False) def save(self, *args, **kwargs): # save what kind we are. self.subclass = self.__class__.__name__ super(Item, self).save(*args, **kwargs)
  18. 18. 子モデル取得関数 def as_child(self): return getattr(self, self.subclass.lower())
  19. 19. 例: i=Item.objects.get(id=1) child=i.as_child()
  20. 20. どう動くか見てみましょう
  21. 21. Model : 2, Mata Options Django のモデルの情報を取得するのに Meta オプションは重宝します
  22. 22. Django Models Internals Documentation https://django-model-_meta- reference.readthedocs.org/en/latest/index.html
  23. 23. get_all_related_objects_with_model Returns a list of (related-object, model) pairs. Similar to get_fields_with_model(). Related オブジェクトのペアのリストを返します 例: [(<RelatedObject: common:sandwich related to item_ptr>, None), (<RelatedObject: common:onigiri related to item_ptr>, None)]
  24. 24. get_parent_list Returns a list of all the ancestor of this model as a list. Useful for determining if something is an ancestor, regardless of lineage. 全てのこのモデルの親(先祖)のリストを返します (私の実機では list ではなく set オブジェクトでした) 例: set([<class 'common.models.Item'>])
  25. 25. get_latest_by model Manager の latest() , earliest() メソッドで返さ れるオブジェクトの判断基準を設定 例: get_latest_by = "order_date"
  26. 26. ordering オブジェクトのリストを取得するときに使われ る、オブジェクトのデフォルトの並び順規則を設 定 例: ordering = ['-order_date']
  27. 27. db_table モデルの使うデータベーステーブルの名前 例: db_table = 'music_album'
  28. 28. Template : 1, Python Template Engine ・Django Template ・Jinja2 ・Mako ・Chameleon
  29. 29. Django Template ・Django 標準のテンプレートエンジン ・Django のテンプレート言語は、釣合いの取れたパワーと簡便さを実現するように、 また HTML を扱い なれた人にとっては快適になるように設計されています。 Smarty や CheetahTemplate のようなテキスト ベースのテンプレート言語を経験 したことがあるなら、 Django のテンプレートはしっくりくるはずで す。 ・プログラミングの知識があったり、 PHP のようなプログラムコードを直接 HTML に混ぜ込む言語を 使ったことがあるなら、 Django のテンプレートシステ ムが単に HTML に Python を埋め込んだものでない ことに疑問を持つでしょう。 しかし、これは設計上意図して決まっていることです。テンプレートシステ ム はプレゼンテーション層を表現するためのもので、プログラムロジックではな いのです。 ・http://docs.djangoproject.jp/en/latest/topics/templates.html
  30. 30. 簡潔で可読性の高いコード Test[“a”] → {{ Test.a }} Test[“a”][“b”] → {{ Test.a.b }} Test[a].b() → {{ Test.a.b }} Test.a.b → {{ Test.a.b }}
  31. 31. Jinja 2 ・Django Template のパワーアップ版 ・書式はほぼ同じなので移植しやすい ・高速 ・おすすめ!
  32. 32. Django Template との比較 ・Method Calls 例: a.b() → {{ a.b() }} (必ず) a[“b”] → {{ a[“b“] }} (任意) ・Conditions 例: {% ifequal a b %} が無効。 代わりに {% if a == b%} を使用。 ・Filter Arguments 例: {{ items|join:", " }} → {{ items|join(', ') }}
  33. 33. Mako <%inherit file="base.html"/> <% rows = [[v for v in range(0,10)] for row in range(0,10)] %> <table> % for row in rows: ${makerow(row)} % endfor </table> <%def name="makerow(row)"> <tr> % for name in row: <td>${name}</td> % endfor </tr> </%def>
  34. 34. Mako = 高機能 先ほどのコードを見てみると Django Template では とてもではないが表現できるものではないことがわかる。 コードの可読性は Django より劣る傾向にあるだろう しかし表現の幅は広がるだろう
  35. 35. 正確で厳しいコード Test[“a”] → ${ Test[“a”] } Test[“a”][“b”] → ${ Test[“a”][“b”] } Test[a].b() → ${ Test[a].b() } Test.a.b → ${ Test.a.b }
  36. 36. Chameleon <html> <meta> <title tal:content="context.title" /> </meta> <body> <div tal:condition="items"> <p>These are your items:</p> <ul> <li tal:repeat="item items" tal:content="item" /> </ul> </div> </body> </html>
  37. 37. Chameleon TAL≒ ・TAL とは Zope のテンプレートエンジン ・Chameleon はそれをベースに改良したテンプ レートエンジン ・XMLベース
  38. 38. Django の XML ベーステンプレートエンジンに対する 評価 ① 「それは、 Django のテンプレート言語を XML/HTML テンプレート 以外にも使いたいと考えているからです。 」 Django テンプレートエンジンについて 「World Online では、email や JavaScript、 CSV にテンプレートを 使っています。テンプレートはテキストベースの形式なら何にでも 使 えるのです。」 http://docs.djangoproject.jp/ja/latest/topics/templates.html
  39. 39. まず・・・ 例: polls/ models.py templatetags/ __init__.py poll_extras.py views.py カスタムテンプレートタグ・フィルターは Django アプリケーションのフォルダ内の templatetags フォルダ内のファイルに記述 https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
  40. 40. Django の XML ベーステンプレートエンジンに対する 評価 ② そう、もう一つあります: 人間に XML を編集させるなんて、 サディスティック でしかありません! http://docs.djangoproject.jp/ja/latest/topics/templates.html
  41. 41. Template : 2, Custom tags and filters 今回は Django Template において説明します
  42. 42. django/template/defaultfilters.py from django.template.base import Library register = Library() @register.filter(is_safe=True) @stringfilter def lower(value): """Converts a string into all lowercase.""" return value.lower()
  43. 43. Django のソースを読むとわかる! テンプレートのフィルターの書き方は Python の 関数 の書き方と同じ!
  44. 44. まず・・・ 例: polls/ models.py templatetags/ __init__.py poll_extras.py views.py カスタムテンプレートタグ・フィルターは Django アプリケーションのフォルダ内の templatetags フォルダ内のファイルに記述 https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
  45. 45. フィルターを登録 例: from django.template.base import Library register = Library() @register.filter() def nothing(value): pass フィルターを登録し完了
  46. 46. タグの場合も同じく 例: from django.template.base import Library register = Library() @register.tag def nothing(value): pass タグを登録し完了
  47. 47. View : 1, Sessions
  48. 48. セッションとは ユーザがあるサイトを訪れてからそこを離れるまでの一連の 通信。 HTTP自体にはユーザを識別する機能が存在しないの で、Cookieなどを使用して同一人物か否かを識別する。 たとえば、はてなにログインしてからログアウトするまでの すべての操作は一つのセッションと考えられる。 http://d.hatena.ne.jp/keyword/%A5%BB %A5%C3%A5%B7%A5%E7%A5%F3
  49. 49. 変数の保存 例: request.session[“Height”] = 120
  50. 50. 変数の取得 例: request.session.get('Height', 0): get(key, default=None) 例: fav_color = request.session.get('fav_color', 'red')
  51. 51. 変数の削除 例: del request.session[“Height”]
  52. 52. 簡単!
  53. 53. View : 2, Cookie
  54. 54. クッキーの保存 HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False) 例: response = render_to_response(template_name, context) response.set_cookie('Height', ') return response HttpResponse.set_cookie であることに注意
  55. 55. クッキーの取得 例: request.COOKIES.get('Height')
  56. 56. 簡単!
  57. 57. View : 3, Cache
  58. 58. キャッシュとは 使用頻度の高いデータを高速な記憶装置に蓄えておくことに より、いちいち低速な装置から読み出す無駄を省いて高速化 すること。また、その際に使われる高速な記憶装置や、複製 されたデータそのもののこと。 http://e-words.jp/w/E382ADE383A3E38383E382B7E383A5.html
  59. 59. キャッシュの設定 Memcached データベースを使ったキャッシュ データベースを使ったキャッシュと、マルチデータ ベース ファイルシステムを使ったキャッシュ ローカルメモリ上のキャッシュ ダミーキャッシュ (開発用)
  60. 60. 例:Memcached settings.py に CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedC ache', 'LOCATION': '127.0.0.1:11211', } }
  61. 61. サイト単位のキャッシュ MIDDLEWARE_CLASSES = ( 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ) http://docs.djangoproject.jp/en/latest/topics/cache.html#id10
  62. 62. ビュー単位のキャッシュ from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): … 又は from django.views.decorators.cache import cache_page urlpatterns = ('', (r'^foo/(d{1,2})/$', cache_page(60 * 15)(my_view)), ) http://docs.djangoproject.jp/en/latest/topics/cache.html#id10
  63. 63. テンプレートの部分的キャッシュ {% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %} http://docs.djangoproject.jp/en/latest/topics/cache.html#id10
  64. 64. 2,ネイティブアプリケーションとの 連携
  65. 65. ネイティブアプリケーション ネイティブアプリケーションとの連携について 実際にはクライアントの作成に等しいが、 Django の ネイティブアプリケーション のクライ アントの作成事例を中々見かけないのでこの題に 設定した。 Qt を使用し実装してみる
  66. 66. まずは OAuth の説明 OAuth とは・・・ ・「OAuth (オー オース[1]) は、ブレイン・クックとクリス・メッ シーナが始めたオープンプロトコルであり、デスクトップ、モバ イル、WebアプリケーションなどにセキュアなAPI認可 (authorization) の標準的手段を提供する。」(Wikipedia) ・要は API 用の認証手段である
  67. 67. 詳しい説明 ● http://www.atmarkit.co.jp/fsecurity/rensai/digid01/02.htm
  68. 68. 準備 ● Django の OAuth2 実装に django-oauth-plus を使用。 ● Django の API 実装に django-tastypie を使用。
  69. 69. INSTALLED_APPS に以下を追記 INSTALLED_APPS = ( 'tastypie', 'oauth_provider', )
  70. 70. まずは API を実装 common/api.py from tastypie.resources import ModelResource from common.models import Onigiri class OnigiriResource(ModelResource): class Meta: queryset = Onigiri.objects.all() resource_name = 'onigiri
  71. 71. Urlsの編集 ecsite/urls.py from tastypie.api import Api from django.contrib import admin admin.autodiscover() onigiri_resource = OnigiriResource() v1_api = Api(api_name='v1') v1_api.register(OnigiriResource()) urlpatterns = patterns('', url(r'^api/', include(onigiri_resource.urls)), )
  72. 72. 完成!(例) $ curl http://127.0.0.1:8000/api/v1/onigiri/?format=json {"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, "objects": [{"guzai": "gre", "id": 1, "price": 436, "resource_uri": "/admin/v1/onigiri/1/", "subclass": "Onigiri", "title": "sdg"}]}
  73. 73. しかしこの状態では However, if you try sending a POST/PUT/DELETE to the resource, you find yourself getting “401 Unauthorized” errors. For safety, Tastypie ships with the authorization class (“what are you allowed to do”) set to ReadOnlyAuthorization. This makes it safe to expose on the web, but prevents us from doing POST/PUT/DELETE. Let’s enable those: http://django-tastypie.readthedocs.org/en/latest/tutorial.html POST/PUT/DELETE が使用できない → つまり API として利用するには取得しか出来ない!
  74. 74. 認証・権限の実装 common/api.py from tastypie.authentication import OAuthAuthentication from tastypie.authorization import DjangoAuthorization from tastypie.resources import ModelResource from common.models import Onigiri class OnigiriResource(ModelResource): class Meta: queryset = Onigiri.objects.all() resource_name = 'onigiri authentication = OAuthAuthentication() authorization = DjangoAuthorization
  75. 75. 同じコマンドを実行 $ curl http ://127.0.0.1:8000/api/v1/onigiri/?format=json Invalid request parameters.
  76. 76. OAuth実装完了!
  77. 77. 検証: Consumer を作成 $ ./manage.py shell >>> from oauth_provider.models import Consumer, Token >>> c = Consumer() >>> c.generate_random_codes() >>> c <Consumer: Consumer with key b10945ea448344bb8d2c7f33d38f2f0d> >>> c.key u'b10945ea448344bb8d2c7f33d38f2f0d' >>> c.secret U'AQsJnvVYn04njIVK' http://d.hatena.ne.jp/yuheiomori0718/20120924/1348496794
  78. 78. 検証: Token を作成 $ ./manage.py shell >>> from django.contrib.auth.models import User >>> u = User.objects.all()[0] >>> t = Token() >>> t.user = u >>> t.consumer = c >>> t.token_type = 2 >>> t.resource_id=0 >>> t.generate_random_codes() >>> t.key 'bec4fdc33725458ab2894558014844b7' >>> t.secret U'WgKrSb7QMz9CLZyX' http://d.hatena.ne.jp/yuheiomori0718/20120924/1348496794
  79. 79. ここでこのコマンドを実行 # coding=utf-8 import json import requests from oauth_hook import OAuthHook consumer_key = 'b10945ea448344bb8d2c7f33d38f2f0d' consumer_secret = 'AQsJnvVYn04njIVK' access_token = 'bec4fdc33725458ab2894558014844b7' access_token_secret = 'WgKrSb7QMz9CLZyX' oauth_hook = OAuthHook(access_token=access_token, access_token_secret=access_token_secret, consumer_key=consumer_key, consumer_secret=consumer_secret, header_auth=True) request = requests.Request('GET', "http://127.0.0.1:8000/api/v1/onigiri/?format=json") request = oauth_hook(request) prepared = request.prepare() session = requests.session() resp = session.send(prepared) print resp.text
  80. 80. 結果は {"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, "objects": [{"guzai": "gre", "id": 1, "price": 436, "resource_uri": "/api/v1/onigiri/1/", "subclass": "Onigiri", "title": "sdg"}]}
  81. 81. PyQt で実装
  82. 82. おわり!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×