A. REST
プログラミングは何ですか?
データ構造とアルゴリズムの組み合わせは、?RESTとは何ですか
レビューは、これまでのライブラリ管理システムの検査は行われ、私たちはURLを設計しました:
127.0.0.1:9001/books/
すべてのデータへのアクセス127.0.0.1:9001/get_all_books/
127.0.0.1:9001/books/{id}/
127.0.0.1:9001/books/{id}?method=get 访问单条数据
127.0.0.1:9001/books/add/
127.0.0.1:9001/books/?type=create 创建数据
127.0.0.1:9001/books/delete/
127.0.0.1:9001/books/update/
URL上記の機能も達成することができるが、異なるため個人の習慣などの、同じ関数は(等のエラーメッセージを含む)URLの多種多様な、応答バックデータを生成するフォーマットを定義しているが周りを生じない均一な標準は、存在しません困難インタラクティブ終了。
唯一代表下REST RESTリソースの得られたURLは、ユーザーの行動との間に以下のものを区別するために、HTTPリクエストメソッドは、REST URL設計仕様に準拠の一例です。
設計仕様のURL:
GET:すべてのデータを取得#127.0.0.1:9001/books/
GET:127.0.0.1:9001/books/{id}データ取得部の#
POST:127.0.0.1:9001/books/#増加データ
DELETE :127.0.0.1:9001/books/{id}#削除データ
PUT:127.0.0.1:9001/books/{id}#データの変更
応答仕様のデータを:
GET:戻る127.0.0.1:9001/books/#[{} 、{}、{}]
GET:返す単一127.0.0.1:9001/books/{idデータ#}} {
POST:127.0.0.1:9001/books/加え正常に返さデータ#} {
DELETE:127.0.0.1: 9001 /書籍/ {ID}#リターン空「」
PUT:127.0.0.1:9001/books/{id}#{}戻り、ではない注目フィールドの完全な更新を記録した後
、エラー処理:
{「エラー」: " ERROR_MESSAGE「}
RESTは、ソフトウェアアーキテクチャのスタイル、標準ではなく、また技術であり、それだけで設計原理と制約のセットを提供し、ウェブデータ・インタフェースの設計のための最も人気のあるAPIの設計仕様です。
参考リンク:
http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html
http://www.scienjus.com/my-restful-api-best-practices/
だから、我々はそれが何を重要ではないDjangoのRESTフレームワークとRESTを学ぶつもりですか?
実際には、DRF(DjangoのRESTフレームワーク)は、Djangoの開発のセットは、DRFはDjangoのアプリですので、本質的には、私たちはより良いREST Djangoのアプリケーション、Webアプリケーションの設計仕様を満たすために、です。
第二に、知識の準備ができて
DRF研究、知識のポイントを初めて目の前に:
- CBV(クラスベースビュー)
django.viewsからは表示インポート
クラスLoginView(ビュー):
デフ(自己、リクエスト)を取得:
パスは、
デフ(自己、リクエストを)投稿:
パス 类方法クラスメソッド和classonlymethod
クラスパーソン(オブジェクト):
デフのinit(自己、名前、年齢):
self.name =名前
self.age =年齢#注:Personクラスがロードされると、それはデコレータ関数クラスメソッド(睡眠)を実行し、結果の睡眠が割り当て
@classmethod
DEF(CLS)を眠れる森:#=クラスメソッド同等の睡眠(スリーピング)
(「トムは眠っている」)を印刷@classonlymethod
DEF(CLS)のショッピング:
プリント( "トムは買い物をされました")
()#クラスをPerson.sleepingすることは、直接(@classmethod装飾付き)クラスメソッドを呼び出し
Person.Angel()#クラス(@classonlymethod装飾付き)メソッドを直接呼び出します
人トム(「トム」、「19」)=
Tom.sleeping()#は、直接オブジェクトクラスのメソッドを呼び出すことができます
Tom.shopping()#のbaocuoを、オブジェクトがメソッドで呼び出すことはできません飾ら@classonlymethod
概要:
@classmethod(Pythonの添加デコレータ)メソッドが呼び出され==オブジェクトおよびクラス。==装飾することができる
@classonlymethod(プラスDjangoのデコレータ)が唯一のクラス== ==呼び出すことができます。
- リフレクション、でisinstance()
(1)のgetattr()
説明:GETATTR()関数はオブジェクトの名前を見つけるために、属性名の文字列の名前で呼ばれ、見つかった場合、それは、このオブジェクトのプロパティ値を返した場合、希望デフォルト値を返します。
構文:
GETATTR(オブジェクト、名[、デフォルト])
参数:
オブジェクト-オブジェクト
名-属性文字列、オブジェクトの
デフォルト-デフォルトの戻り値は、パラメータが利用できない場合、トリガーはAttributeErrorには対応する属性が存在しない
戻り値:戻りオブジェクトのプロパティ
(2)はhasattr()
説明:オブジェクトは、対応するプロパティが含まれているか否かを決定するためはhasattr()関数。
構文:
hasattr(オブジェクト、名)
パラメータ:
オブジェクト-オブジェクト
名-文字列、属性名
戻り値:属性名は、オブジェクトの名前がオブジェクトに存在している場合、それはそうでなければFalse、Trueを返します。
(3)SETATTR()
説明:再度設定した目標オブジェクトの名前属性値の関数getsttrに対応setsttr()関数()、名前の属性が存在しなければならないことに注意してください。
構文:
SETATTR(オブジェクト、名前、値)
参数:
オブジェクト-オブジェクト
名-文字列、オブジェクト属性
値-属性値
戻り値:なし
(4)でisinstance()
説明:でisinstance()関数は、オブジェクトが既知のタイプであるかどうかを決定するために使用されます。
isinstence()とタイプ()の違い:
-タイプ()の継承に関係なく、その親クラスタイプのサブクラスであるとは思いません。
- 。Isinstence()、サブクラスは親クラスのタイプであると考え継承を検討される
二つのタイプが同じであるかどうかを判断するには推奨isinstence()。
構文:
isinstence(オブジェクト、CLASSINFO)
パラメータ:
オブジェクト-インスタンスオブジェクト
CLASSINFOは-直接または間接的に、クラス名であってもよいし、基本的な種類がそれらで構成されるタプル
戻り値:真二つのタイプ(CLASSINFO)のパラメータの型は、オブジェクトが、そうでなければFalse同じであれば場合。
位置決め自己
我々が明確でなければならないが、自己は常に== ==、発信者を指しています。HTTP要求プロトコル
契約は、である、規範規範に両側を通信する分析データのルールENCTYPEプロパティシート状三のプロトコル要求がある
ユーザーフォーム形式で送信されたデータは、データコードするプロトコルを定義するために、フォームのenctype属性を形成するために使用することができる場合、プロパティは、プロトコルをコードする3つのデータを表す、3つの値があります。
アプリケーション/ X-WWW-フォーム- urlエンコード: この値は、キーと値のペア&シンボリックリンクを複数使用され、スプライスと、キーと値のペアは、enctypeを値がデフォルト属性です等しい。
アップロードファイル、写真:マルチパート/フォームデータこの値が使用されます。
テキスト/平野:スペースは+に変換されます。
- JavaScriptオブジェクトで(例えば:{名: 'アレックス'} <==> JSON) 相互変換方法
JSON.stringify(データ)==>対応するPythonのjson.dumps()に
JSON.parse(データ)== >等価json.loadsパイソン()
3。ジャンゴRESTフレームワーク(DRF) - なぜ使用DRF?
DRFでの本質は、それは、そのようなアプリケーションで、私たちはより良い== == RESTfulなWebアプリケーションの仕様に準拠しています。実際には、でも、DRFせずに設計することができ、Djangoのアプリです我々はまた、次の例をRESTfulなWebアプリケーションに合わせて、独自の仕様を設計することができます。
django.shortcutsからのHttpResponseをインポートする
ビューをインポートdjango.viewsから
*インポートモデルから
JSONインポート
:クラスCourseView(ビュー)
デフ(自己、リクエスト)を取得:
course_list =リスト()
for course in models.Course.objects.all():
course = {
'course_name': course.course_name,
'description': course.description,
}
course_list.append(course)
return HttpResponse(json.dumps(course_list, ensure_ascii=False))
でもDRFずに、上記のコードでは、我々はすべてのコースデータを取得し、RESTの仕様に基づいて、リストを介してユーザに返されるすべてのリソースは、我々が見ることができ、我々はまた、RESTfulな仕様、さらには全体のAppアプリケーションとのインタフェース準拠を設計することができます。すべてのインターフェイスは、カスタムされている場合には、必然的にコードの重複、効率を向上させるために、我々は良いツールを使用することをお勧めしますがあるだろう、DRFは、加えて、それは私たちだけがすぐにRESTfulな仕様を満たすように設計するために、このような素晴らしいツールを助けることはできませんされてインターフェースはまた、認証、許可、等のような他の強力な機能を提供します。
DRFを使用する場合は?
あなたは、あなたがフラスコのRESTfulを使用することができフラスコを使用している場合は、その後、DRFを使用しようとすると、WebアプリケーションのDjangoの開発を使用する場合はRESTfulなAPIは、最も人気の高い設計仕様です。DRF利用
DRF公式文書
DRFのインストール
ジャンゴインストール
ピップジャンゴインストール
インストールdjangorestframework
ピップdjangorestframeworkインストール
インストールが完了したら、私たちは私たちのウェブアプリケーションフレームワークは、以下の知識点を含む達成するためにDRFフレームワークを使用するために始めることができます。
- APIView
-パーサーコンポーネント
-アセンブリシリアライゼーション
-組立図
-認証コンポーネント
-範囲の成分
-周波数制御アセンブリ
-ページングコンポーネント
-各アセンブリ
- URLコントロール
- APIViewの
導入DRFは、APIViewを導入しなければならない、それはすべての==リクエストがAPIViewで配布されることになる==ので、次のすべてのコンポーネントの基本で、最も重要である。だから、正確に?欲しいの要求にそれを配布する方法その後、彼らはこの問題把握する必要があり、我々はそのソースコードを解釈する必要がありますが、DRFのAPIViewのソースコードを解釈したい、あなた必要がありジャンゴviews.Viewクラスのソースコードを、なぜ使用ビュー機能コールas_view()のように、リクエストに応じて最初の図異なる機能は、それを扱うことができますか?
(1)レビューCBV、読書ソースを表示
urls.pyコードは次のよう:
django.urlsのインポートパスから、含み、re_path
classbasedViewインポートビューから
urlpatterns = [
re_path( 'ログイン/ $'、views.LoginView.as_view())]
views.pyコードは次のよう:
インポートからビューをdjango.views
クラスLoginView(ビュー):
DEF GET(セルフ、要求):
パス
DEF POST(自己、要求):
パス
上のコードの実行フローは、以下の(出典解釈):
(1)スタートのDjangoプロジェクト、後のpython manage.pyのrunserver 127.0.0.1:8000の、すなわち実装
(2)コンフィギュレーションファイルのsettings.pyのロードを開始
models.py読み
負荷views.py
)ロードされたurls.py、実行as_viewを(: views.LoginView.as_view()
次のようにこうして方法as_view親クラスビュー、ビュー関連するソース親クラスを行う、何as_viewのLoginViewがないので(3):
クラス・ビュー:
http_method_names = [「GET」、「POST」、「PUT 」、...]
DEF のinit(セルフ、kwargsから**):
キー、(中kwargs.items値)について:
SETATTR(セルフ、キー、値)
@classonlymethod
def as_view(cls, **initkwargs):
for key in initkwargs:
...
def view(request, * args, **kwargs):
"""
实例化一个对象,对象名称为self,self是cls的对象,谁调用了as_view,cls就是谁(当前调用as_view的是LoginView),所以,此时的self就是LoginView实例化对象.
"""
self = cls(**initkwargs)
if hassttr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initwargs
update_wrapper(view, cls, updated=())
update_wrapper(view, cls.dispatch, assigned=())
return view
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_name:
# 通过getattr找到的属性,已和对象绑定,访问时不需要再指明对象了
# 即不需要再: self.handler, 直接handler()执行
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
上記から分かるas_view源がクラスメソッドであり、ビュー関数で定義された方法、及び図as_view関数戻り、この時点では一つの機能との対応関係を確立し、ユーザの要求を待って開始URL。
リクエストが(例えば、GET要求など)は、ユーザーによって送信された場合(4)、開始ビュー機能をURLに対応する、とリクエストオブジェクトを渡し、実行結果を表示クラスビュー機能はself.dispatch(リクエスト、* argsを、**返すことである kwargsからのLoginViewメソッドをディスパッチしないので)、実行結果、自己は、本明細書にそうディスパッチ親クラスAPIViewを実行するために同じ、APIViewクラスのディスパッチ機能も反射によって自己を見つけ、インスタンスオブジェクトLoginViewを指す(この自己がそのクラスのメソッド(すなわちLoginView)を取得)オブジェクトLoginViewのインスタンスを参照する場合、ディスパッチ機能ハンドラ(要求、*引数、** kwargsから)が実行LoginViewクラスのgetメソッドを表し、実行結果の発送です、リクエストURL表示機能に対応する実行結果である実行結果は、最終結果がユーザに返される。
(2)APIViewの
使用:
views.pyコード:
rest_framework.viewsからAPIView#引入APIViewインポート
#继承APIView:クラスLoginView(APIView)
デフのget(自己、リクエスト):
合格
(自己、リクエスト)を投稿DEF:
パスを
urls.pyコード:
インポートパスとしては、django.urlsから、re_path
classbasedViewインポートビューから
urlspatterns = [
re_path( 'ログイン/ $'、views.LoginView.as_view())]
源码解读:
(1)スタートジャンゴプロジェクト:Pythonは127.0.0.1:8000のrunserverをmanage.pyの
(2)settings.pyファイルのロード開始
ファイルを読み取るmodels.pyの(3)を
views.pyファイルをロード(4)
(5)にロードurls.pyをファイルの実行as_view():views.LoginView.as_view()
なしas_viewのLoginViewはありませんので、これas_view APIViewに親クラスを実行するために、親クラスAPIView関連するソースは、以下の(6):
クラスAPIView(ビュー):
.. 。
#api_settingsオブジェクトクラスのインスタンスであるAPISettings
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
...
設定= api_setings
スキーマ= DefaultSchema()
@classmethod
def as_view(cls, **initkwargs): # cls指LoginView
if isinstence(getattr(cls, 'queryset', None), models.query.Queryset):
...
# 下面一句表示去执行APIView父类(即View类)中的as_view方法
view = super(APIView, cls).as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
return csrf_exempt(view)
def dispatch(self, request, *args, **kwargs):
...
request = self.initialize_request(request, *args, **kwargs)
...
try:
self.initial(request, *args, **kwargs)
if request.method.lower() in self.http_method_name:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = self.handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
上記の解釈に見るソース参照は、我々はas_viewメソッドView戻り値は、関数、この時点でURLに対応するビューがすでに確立されている、要求のためのユーザ待ちを閲覧知っています。
リクエストが(例えば、GET要求など)は、ユーザーによって送信された場合には(7)、開始ビュー機能をURLに対応する、とリクエストオブジェクトを渡し、実行結果を表示クラスビュー機能はself.dispatch(リクエスト、* argsを、**返すことである kwargsからの)実行結果、自己オブジェクトLoginView、LoginViewない発送方法は、それが同様に親クラスAPIViewの方法を実行するためにディスパッチインスタンスを指し、APIviewクラスのディスパッチ機能はこの場合、自己反射(によって発見されますクラスのメソッドを取得する)自己LoginViewのオブジェクトインスタンスを指す(すなわちLoginView)であり、関数ディスパッチハンドラ(要求、*引数、**に kwargsから) 実行結果ディスパッチの実行結果であるGETメソッドLoginViewクラスを示します、これは、対応するビューのURLの結果の機能を実行するように要求され、最終結果がユーザに返される。
IV。補足知識
- デコレータでは
クラスは装飾的な機能、そしてクラスローディング時間、デコレータ関数を実行、次のコードがある場合:
クラスパーソン(オブジェクト):
@classmethod#相当于睡眠=クラスメソッド(睡眠)
デフ(CLS)を寝:
プリント( 'トムは眠っています')
print(sleeping)
# 加载类时执行,结果是:<classmethod object at 0x000001F2C29C8198>
注:このクラスは、ダイレクトプリントやプリント出力を実行すると、関数呼び出しは次のようにする場合にのみ実行されます。
デフFUNC():
プリント( 'Hello Worldの!')
印刷関数funcを実行していないロード
それは我々がFUNCを呼び出すとき()印刷を実行しますのみです
__dict__方法
クラスパーソン(オブジェクト):
デフのinit(自己、名前、年齢):
self.name =名前
self.age =年齢デフ(自己)歌わ:
プリントを(「私は歌いますよ!」)
P1 =人( 'アレックス'、18)
プリント(P1 .__ dict__に)#{ '名前': 'アレックス'、 '年齢':18}
プリント(人物.__ dict__に)
'' '
{' モジュール ':' 主」、
' INIT ':<0x0000021E1A46A8C8での関数人.__ init__>、
'歌う'、<0x0000021E1A46A950でPerson.sing機能>
' 辞書 ':<属性' 辞書 '人'のオブジェクトの'>、
" weakref ':<属性' weakref人の''オブジェクト>、
「DOC ':なし}
'''
总结:
dict__にすべてのメンバーが辞書オブジェクトに戻すオブジェクトは.__;
クラス.__ dict__に戻り辞書のクラスのすべてのメンバーを、
我々はオブジェクトを介して.nameのメンバーを削除することができ、オブジェクトの.nameの自然を使用してそのような値の辞書的には、クラスを実行することではないのGetItemメソッドを。
- プログラムの機能を拡張するには、2つの方法は
以下の2つの要件があります。
需要:以下の機能を追加した時間を計測する(前提を書き換えることなく、機能を追加します)
DEF追加(X、Y):
リターンX + Y
ソリューション:デコレータ
DEF外側(FUNC):
DEF内(*引数、** kwargsから):
インポート時間
START_TIME = time.time()
RET = FUNC(*引数、** kwargsから)
END_TIME = time.time()
プリント(END_TIME - START_TIME)
リターンインナー
@outer
DEF(x、y)を追加します。
復帰X + Y
二つの要件:(前提父クラスを書き換えることなく)機能の拡張クラス
クラスの父(オブジェクト):
デフショー(自己):
プリント(「父親のショーがexcutedさ!」)
父=父()
father.show()
ソリューション:継承父クラスは、スーパーでshow()メソッドの呼び出しを無効にするクラスを再書き込み()
クラス息子(父):
デフを示し(自己):
プリント( '息子のショーがexcutedされる!')
スーパー()を示して()。
=息子の息子()
son.show()
概要:
プロセス指向プログラムの機能を拡張する方法:
デコレータ
プログラムの機能を拡張するためのオブジェクト指向方法:
クラス継承
メソッドのオーバーライド
スーパー()メソッドは、親クラスを行います
- スーパー()関数
の説明:スーパー()関数は、単一継承を使用して直接際に問題なく、親クラスのメソッドを呼び出すために、クラス名での問題を解決するために使用された多重継承のスーパーの親クラス(スーパークラス)を呼び出す方法です。あなたは多重継承を使用する場合は、検索順序(MRO)、繰り返し呼び出し(ダイヤモンド継承)やその他の問題があります。
MROは道クラスの解決順序テーブルで、実際には、継承の順位表は時に親クラスのメソッドです。
構文:
スーパー(タイプ[、オブジェクトまたは型])
参数。
タイプ-クラス
オブジェクトまたは式-ベースの、一般的に自己
戻り値:なし
== ==注:違いPython3.xとPython2.xは次のとおりです。Pyhton3はなく直接XXXのスーパー(クラス、自己).XXXのsuper()を使用することができます。..
スーパーでPython3.x Python2.x()使用法の比較:
Python3.x例:
クラスA:
パス
クラスB(A):
DEF(自己、X)を追加します
。スーパー()(X)を追加
Python2.x例:
クラスA(オブジェクト):#Python2.xが継承オブジェクトに覚え
峠
クラスB(A):
DEF追加(X):
スーパー(B、セルフ).add(X)
の例を:
クラスFooParent(オブジェクト):
デフのinit(自己):
self.parent = '私は親です!'
印刷(「親」)
def bar(self, message):
print('%s from Parent!' % message)
クラスFooChild(FooParent):
DEF INIT(自己):
'' '
、参考としてスーパー(B、セルフ)を形成する
、第一FooChild親(すなわちFooParent)を見つけるスーパー(FooChild、セルフ)
、クラスB(すなわちをスーパー()最初のパラメータ)は、オブジェクトFooChild FooParentオブジェクトに変換されます
' ''
__ .__のinit()スーパー(FooChild、セルフ)
印刷('子「)
def bar(self, message):
super(FooChild, self).bar(message)
print('Child bar function!')
print(self.parent)
もし名前 == ' メイン ':
fooChild = FooChild()
fooChild.bar(' HelloWorldの')