【Django】前后端数据传输,查询字符串、路径参数、表单数据、非表单数据、请求头

1.查询字符串

前端要把参数传给服务器,可以通过查询字符串的方式,即在资源路径后面加上一个?号,再拼接查询参数,例如http://localhost/XXXX/?name=pan&age=18

我们在一个子应用的视图函数写一个接收查询字符串的类,并且get()和post()方法都实现,因为不管使用哪种请求方式,都可以接收到查询参数

urls.py

from . import views

urlpatterns = [
    path('request_info/', views.RequestInfo.as_view()),
]

views.py

from django.views import View
from django import http

# 接收查询字符串: http://localhost/XXXX/?name=pan&age=18
# 提取查询字符串参数不区分请求方式,即使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串参数。
class RequestInfo(View):
    def get(self, request):
        # 使用get()方法获取数据,若不存在该参数名,则可以设置默认值
        # 需要注意的是,如果出现重复赋值,get()方法只会获取最后一个数值
        name = request.GET.get('name', '小明')
        age = request.GET.get('age', '0')
        # 也可以直接使用键取值
        # print(request.GET['age'])
        
        # 也可以接收全部重复数值,例如下面的链接,age重复了 多次
        # http://localhost:8000/request_info/?name=xiaohei&age=18&age=20&age=22
        args = request.GET.getlist('age')  # 接收全部age的数值,并且保存在一个列表
        print(args)
        return http.HttpResponse('姓名是%s,年龄是%s' % (name, age))

    def post(self, request):
        name = request.GET.get('name', '小明')
        age = request.GET.get('age', '0')
        return http.HttpResponse('姓名是%s,年龄是%s' % (name, age))

我们注册好子路由和主路由之后就可以正常获取到传递的参数了

2.URL路径参数

2.1 path()简单提取

除了使用?拼接字符串,路径也是可以传递参数的,例如http://localhost:8000/request_goods/22/33/,url最后的22和33就是两个参数,具体几个参数我们可以指定,并且可以指定参数名

urls.py

from django.urls import path, re_path
from . import views

urlpatterns = [
   ...
    # <>内表示参数的名字,引用的时候也要用这参数名
    path('request_goods/<page>/<gid>/', views.RequestGoods.as_view()),
    # 也可以指定参数的类型,如int
	# path('request_goods/<int:page>/<int:gid>/', views.RequestGoods.as_view()),
	...
]

views.py

from django.views import View
from django import http

# 获取url携带的路径参数
# http://localhost:8000/request_goods/22/33/
class RequestGoods(View):
    # 传入的两个参数page和gid要在路由表声明
    def get(self, request, page, gid):
        return http.HttpResponse('当前第%s页,第号%s商品' % (page, gid))

在路由列表里指定参数的时候是可以指定参数类型的,默认的有5种类型

默认的路由转换器:

DEFAULT_CONVERTERS = {
    
    
    'int': IntConverter(), # 匹配正整数,包含0
    'path': PathConverter(), # 匹配任何非空字符串,包含了路径分隔符
    'slug': SlugConverter(), # 匹配字母、数字以及横杠、下划线组成的字符串
    'str': StringConverter(), # 匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    'uuid': UUIDConverter(), # 匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
}

如果觉得默认的路由转换还不够,可以自定义,但是因为比较麻烦,我们还是直接在路由时使用正则匹配吧

2.2 re_path()正则提取

我们可以在路由的时候从路径提取要传递的数据,使用re_path()函数进行匹配

urls.py

from django.urls import path, re_path
from . import views

urlpatterns = [
  	...
    # <>内表示参数的名字,引用的时候也要用这参数名
    path('request_goods/<page>/<gid>/', views.RequestGoods.as_view()),
    
    # 使用正则匹配手机号,并且指定参数名
    re_path(r'^request_phone/(?P<phone_num>1[3-9]\d{9})/$', views.ResponsePhoneNumber.as_view()),
	...
]

注意:写正则的时候,1.使用^、$指定前后字符串,2.使用圆括号分组起别名

view.py

from django.views import View
from django import http

# http://localhost:8000/request_phone/13977778888/
class ResponsePhoneNumber(View):
	# 这里的phone_num参数由路由时指定
    def get(self, request, phone_num):
        return http.HttpResponse('提取到的手机号是:%s' % phone_num)

3.接收请求体数据

3.1 接收表单数据

urls.py

from django.urls import path, re_path
from . import views

urlpatterns = [
    ...
    path('formdata/', views.FormdataView.as_view()),
	...
]

views.py

from django.views import View
from django import http

# 接收表单数据
class FormdataView(View):
    # 注意,表单数据只能通过post获取
    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        return http.HttpResponse('用户名是:%s,密码是:%s' % (username, password))

注意:

  • 接收表单数据,只能通过post()方法处理
  • 如果出现csrf中间件阻止,可以打开项目的settings.py找到MIDDLEWARE列表,把csrf那一项注释掉
3.2 接收非表单数据

客户端发送过来的如果不是表单数据,则会被保留最原始的格式,可以通过request.body属性获取到bytes类型的二进制数据

我们这里以json数据为例

urls.py

from django.urls import path, re_path
from . import views

urlpatterns = [
 	...
    path('formbody/', views.Bodydata.as_view()),
]

views.py

from django.views import View
from django import http
import json

# 除了查询字符串和表单数据,其他的数据都会被保留原始数据
# 例如由前端发送过来的json数据
class Bodydata(View):
    def post(self, request):
        json_str = request.body
        json_dic = json.loads(json_str) # 把字符串转换成对象
        username = json_dic.get('username')
        password = json_dic.get('password')
        print(json_str)
        return http.HttpResponse('通过非表单提交的数据,用户名:%s,密码: %s' % (username, password))

4.接收请求头数据

浏览器在请求服务器的时候会在请求头夹带数据,这些数据可以通过request.META属性获取到,我们可以通过键来取出对应的值,例如我们可以取出比较常用的

请求头 说明
CONTENT_LENGTH 请求头的字符串长度
CONTENT_TYPE 请求体的MIME文件类型
HTTP_ACCEPT 响应时可接受的类型
HTTP_HOST 主机地址
HTTP_REFERER 关联的地址
HTTP_USER_AGENT 浏览器代理

浏览器发出的请求头也是键值对方式的,但是浏览器的键与Django取值的键是有些不一样的

如果想查看更多请求头的信息,可以把request.META打印出来看一下

除了以上这些比较常用的请求头数据之外,我们还可以发送自定义的键值对,在服务端使用get()方法接收即可,需要注意的是,键会发生变化,改成“HTTP_大写键”

views.py

from django.shortcuts import render
from django.views import View
from django.http import HttpResponse
import json


class FormdataView(View):
    def post(self, request):
        print('=' * 30)
        print(request.POST.get('name'))
        print('=' * 30)
        return HttpResponse('提交表单')

    def get(self, request):
    	# 取值的键发生变化,原有的键名变成大写,再加上“HTTP_”前缀
        print(request.META.get('HTTP_NAME', '没有值'))  
        print(request.META.get('HTTP_PASSWORD', '没有值'))
        return HttpResponse('非表单数据')

使用postman发送header键值对数据
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39147299/article/details/108264932