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的字符串
-------------------------------------------
个性签名:不忘初心,方得始终!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!