根據請求頭content-type
選擇對應的解析器對請求體內容進行處理。有application/json
,x-www-form-urlencoded
,form-data
等格式css
settings.py
配置REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser' 'rest_framework.parsers.FormParser' 'rest_framework.parsers.MultiPartParser' ] }
urls.py
配置urlpatterns = [ url(r'test/', TestView.as_view()), ]
views.py
from rest_framework.views import APIView from rest_framework.response import Response class TestView(APIView): def post(self, request, *args, **kwargs): print(request.content_type) # 獲取請求的值,並使用對應的JSONParser進行處理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
content-type
爲application/json
的請求體urls.py
from django.conf.urls import url, include from web.views.s5_parser import TestView urlpatterns = [ url(r'test/', TestView.as_view(), name='test'), ]
views.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser class TestView(APIView): parser_classes = [JSONParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 獲取請求的值,並使用對應的JSONParser進行處理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
content-type
爲application/x-www-form-urlencoded
的請求體urls.py
from django.conf.urls import url, include from web.views import TestView urlpatterns = [ url(r'test/', TestView.as_view(), name='test'), ]
views.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FormParser class TestView(APIView): parser_classes = [FormParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 獲取請求的值,並使用對應的JSONParser進行處理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
content-type
爲multipart/form-data
的請求體urls.py
from django.conf.urls import url, include from web.views import TestView urlpatterns = [ url(r'test/', TestView.as_view(), name='test'), ]
views.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import MultiPartParser class TestView(APIView): parser_classes = [MultiPartParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 獲取請求的值,並使用對應的JSONParser進行處理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
templete.html
<!DOCTYPE html> <html lang="en"> <head> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data"> <input type="text" name="user" /> <input type="file" name="img"> <input type="submit" value="提交"> </form> </body> </html>
urls.py
from django.conf.urls import url, include from web.views import TestView urlpatterns = [ url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'), ]
views.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FileUploadParser class TestView(APIView): parser_classes = [FileUploadParser, ] def post(self, request, filename, *args, **kwargs): print(filename) print(request.content_type) # 獲取請求的值,並使用對應的JSONParser進行處理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
templete.html
<!DOCTYPE html> <html lang="en"> <head> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data"> <input type="text" name="user" /> <input type="file" name="img"> <input type="submit" value="提交"> </form> </body> </html>
Parser
當同時使用多個parser時,rest framework會根據請求頭content-type自動進行比對,並使用對應parserhtml
urls.py
from django.conf.urls import url, include from web.views import TestView urlpatterns = [ url(r'test/', TestView.as_view(), name='test'), ]
views.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser, FormParser, MultiPartParser class TestView(APIView): parser_classes = [JSONParser, FormParser, MultiPartParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 獲取請求的值,並使用對應的JSONParser進行處理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
# 1 在調用request.data時,才進行解析,由此入手 @property def data(self): if not _hasattr(self, '_full_data'): self._load_data_and_files() return self._full_data # 2 查看self._load_data_and_files()方法---->self._data, self._files = self._parse() def _parse(self): #用戶請求頭裏content_type的值 media_type = self.content_type #self.parsers 就是用戶配置的parser_classes = [FileUploadParser,FormParser ] #self裏就有content_type,傳入此函數 parser = self.negotiator.select_parser(self, self.parsers) # 3 查看self.negotiator.select_parser(self, self.parsers) def select_parser(self, request, parsers): #同過media_type和request.content_type比較,來返回解析器,而後調用解析器的解析方法 #每一個解析器都有media_type = 'multipart/form-data'屬性 for parser in parsers: if media_type_matches(parser.media_type, request.content_type): return parser return None # 4 最終調用parser的解析方法來解析parsed = parser.parse(stream, media_type, self.parser_context) # 1 Request實例化,parsers=self.get_parsers() Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context ) # 2 get_parsers方法,循環實例化出self.parser_classes中類對象 def get_parsers(self): return [parser() for parser in self.parser_classes] # 3 self.parser_classes 先從類自己找,找不到去父類找即APIVIew 中的 parser_classes = api_settings.DEFAULT_PARSER_CLASSES # 4 api_settings是一個對象,對象裏找DEFAULT_PARSER_CLASSES屬性,找不到,會到getattr方法 def __getattr__(self, attr): if attr not in self.defaults: raise AttributeError("Invalid API setting: '%s'" % attr) try: #調用self.user_settings方法,返回一個字典,字典再取attr屬性 val = self.user_settings[attr] except KeyError: # Fall back to defaults val = self.defaults[attr] # Coerce import strings into classes if attr in self.import_strings: val = perform_import(val, attr) # Cache the result self._cached_attrs.add(attr) setattr(self, attr, val) return val # 5 user_settings方法 ,經過反射去setting配置文件裏找REST_FRAMEWORK屬性,找不到,返回空字典 @property def user_settings(self): if not hasattr(self, '_user_settings'): self._user_settings = getattr(settings, 'REST_FRAMEWORK', {}) return self._user_settings
jQuery安裝
>: cnpm install jquery
vue/cli 3
配置jQuery
在vue.config.js
中配置(沒有,手動項目根目錄下新建)vue
const webpack = require("webpack"); module.exports = { configureWebpack: { plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", Popper: ["popper.js", "default"] }) ] } };
BootStrap安裝
>: cnpm install bootstrap@3
vue/cli 3
配置BootStrap
在main.js
中配置python
import "bootstrap" import "bootstrap/dist/css/bootstrap.css"