一、請求
Django中前端向后端傳參的方式主要有以下幾種情況:
- 查詢字符串參數
- 請求體參數
- form表單傳參
- json格式參數
- 上傳文件
- 請求頭傳參
- 路徑參數
- url路徑中的參數
但是以上幾種情況在Django中又是怎么做的呢?
我們還是使用之前定義的類視圖:
from django.http import HttpResponse from django.views import View class IndexPage(View): ''' 類視圖 ''' def get(self, request): return HttpResponse("<p>這是一個get請求</p>") def post(self, request): return HttpResponse("<p>這是一個post請求</p>") def delete(self, request): return HttpResponse("<p>這是一個delete請求</p>")
路由定義如下:
from django.contrib import admin from django.urls import path from projects.views import IndexPage urlpatterns = [ path('admin/', admin.site.urls), path('index/', IndexPage.as_view()) ]
1、查詢字符串參數
以postman請求來做演示,查詢字符串一般用在get請求中,也有一些會用在post請求的params中,假設有兩個字段,name='xiaogongjin', 'age'=18,我們在代碼的對應視圖上打上斷點后發送請求
通過pycharm斷點計算器,可以通過如下方式獲取到傳入的字段,傳入的字段數據類型為“QureyDict”,可以類比於python的字典數據類型
如果要知道request.GET支持哪些方法去操作,可以使用dir()方法去查看:
如果我們要獲取name字段的值,則可以使用request.GET.get('name'),拿到值后就可以在類視圖對應的get方法里進行邏輯控制了,這里就不舉例了。
有時候如果查詢字符串中傳入多個一樣的屬性名,而值卻不同,比如:http://127.0.0.1:8000/index/?name=xiaogongjin&name=xiaohua,這時候可以使用request.GET.getlist('name'),它返回一個list
2、請求體參數-form表單
這里依然使用postman做演示,form一般都是用於post請求的body里,Content-Type為application/x-www-form-urlencoded,同樣假設有兩個字段,name='xiaogongjin', 'age'=18,我們在代碼的對應視圖上打上斷點后發送請求
通過pycharm斷點計算器,可以通過如下方式獲取到傳入的字段,傳入的字段數據類型也為“QureyDict”
那么獲取方法跟查詢字符串一致
3、請求體參數-json格式數據
這里依然使用postman做演示,json格式數據一般也是用於post請求的body里,Content-Type為application/json,同樣假設有兩個字段,name='xiaogongjin', 'age'=18,我們在代碼的對應視圖上打上斷點后發送請求
通過pycharm斷點計算器,可以通過如下方式獲取到傳入的字段,傳入的字段數據類型為“bytes”,為json格式數據
4、上傳文件
這里依然使用postman做演示,這里使用的post請求方式,上傳文件選擇binary,我們在代碼的對應視圖上打上斷點后發送請求
通過pycharm斷點計算器,可以通過如下方式獲取到傳入的字段,傳入的字段數據類型也為“bytes”,可以通過上下文管理器去讀寫二進制文件內容
5、請求頭傳參
這里依然使用postman做演示,使用的get請求方式,假設header里面傳入Authorization=xxxx,我們在代碼的對應視圖上打上斷點后發送請求
通過pycharm斷點計算器,可以通過request.headers獲取到所有請求頭的相關信息,並且它傳入的數據類型為“HttpHeaders”,也可以類比為python的字典數據類型
要獲取剛剛自定義的請求頭信息,則可以使用request.headers.get('Authorization')方法
6、路徑參數
這種類型的請求,只在url路徑中傳入的參數,比如傳入的一些id值,這些值一般都是動態的,在Django中,這種類型的請求處理方法跟上面幾種截然不同,我們一般在路由表中進行正則匹配
- 路徑轉換器格式:<url類型轉換器:路徑參數名>
- url類型轉換器:int、path、uuid、slug等
urlpatterns = [ path('admin/', admin.site.urls), path('index/<int:pk>/', IndexPage.as_view()) ]
同樣視圖方法也要定義第二個形參用於接收pk
依然以postman示例:
通過pycharm斷點計算器,就能夠獲取到
二、響應
Django中后端向前端響應,使用的是HttpResponse對象,它繼承HttpResponseBase類,我們通過它們的部分源碼可以看到傳參的方式:
class HttpResponse(HttpResponseBase): """ An HTTP response class with a string as content. This content that can be read, appended to, or replaced. """ streaming = False def __init__(self, content=b'', *args, **kwargs): super().__init__(*args, **kwargs) # Content is a bytestring. See the `content` property methods. self.content = content
class HttpResponseBase: """ An HTTP response base class with dictionary-accessed headers. This class doesn't handle content. It should not be used directly. Use the HttpResponse and StreamingHttpResponse subclasses instead. """ status_code = 200 def __init__(self, content_type=None, status=None, reason=None, charset=None): # _headers is a mapping of the lowercase name to the original case of # the header (required for working with legacy systems) and the header # value. Both the name of the header and its value are ASCII strings. self._headers = {} self._resource_closers = [] # This parameter is set by the handler. It's necessary to preserve the # historical behavior of request_finished. self._handler_class = None self.cookies = SimpleCookie() self.closed = False if status is not None: try: self.status_code = int(status) except (ValueError, TypeError): raise TypeError('HTTP status code must be an integer.') if not 100 <= self.status_code <= 599: raise ValueError('HTTP status code must be an integer from 100 to 599.') self._reason_phrase = reason self._charset = charset if content_type is None: content_type = 'text/html; charset=%s' % self.charset self['Content-Type'] = content_type
- content:響應數據,字符串類型或者字節類型,會將內容返回到前端
- content_type:響應體格式,默認為text/html 也可以設置為:application/x-www-form-urlencoded 或者 application/json 等等
- status:響應狀態碼,默認為200
- chartset:編碼級,默認為UTF-8
如果想直接返回json格式的數據,也可以使用JsonResponse對象,它繼承了HttpResponse的類,前后端分離的項目最常用,源碼如下:
class JsonResponse(HttpResponse): """ An HTTP response class that consumes data to be serialized to JSON. :param data: Data to be dumped into json. By default only ``dict`` objects are allowed to be passed due to a security flaw before EcmaScript 5. See the ``safe`` parameter for more information. :param encoder: Should be a json encoder class. Defaults to ``django.core.serializers.json.DjangoJSONEncoder``. :param safe: Controls if only ``dict`` objects may be serialized. Defaults to ``True``. :param json_dumps_params: A dictionary of kwargs passed to json.dumps(). """ def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs): if safe and not isinstance(data, dict): raise TypeError( 'In order to allow non-dict objects to be serialized set the ' 'safe parameter to False.' ) if json_dumps_params is None: json_dumps_params = {} kwargs.setdefault('content_type', 'application/json') data = json.dumps(data, cls=encoder, **json_dumps_params) super().__init__(content=data, **kwargs)
- data為字典或者嵌套列表的字典,如果為非字典類型,需要將safe參數設置為False
- 該對象返回一個json的字符串