Django請求與響應


一、請求

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的字符串


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM