回想一下,利用HTTP协议向服务器传参有几种途径?

  • 提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取;
  • 查询字符串(query string),形如key1=value1&key2=value2
  • 请求体(body)中发送的数据,比如表单数据、jsonxml
  • 在http报文的头(header)中。

URL路径参数

在路由匹配时,直接使用正则提取出对应参数,传递给视图函数

  • 路由匹配:http://127.0.0.1:8000/weather/2018/beijing
1
2
3
4
5
6
from django.urls import path
from .views import weather

urlpatterns = [
path('weather/<int:year>/<str:city>', weather)
]
  • 视图实现
1
2
3
def weather(request, city, year):
data = "{}年{}的平均气温是28℃".format(year, city)
return HttpResponse(data)

或者当django内置的path函数不能完成正则匹配的任务时,可以使用 re_path 函数,自定义正则表达式 实现参数获取

  • 路由匹配: http://127.0.0.1:8000/user/bookandmusic
1
2
3
4
5
6
7
from django.urls import re_path
from .views import userinfo

urlpatterns = [
re_path(r'^user/(?P<username>[a-zA-Z]\w{7,11})$', userinfo)
]

  • 视图实现
1
2
3
def userinfo(request, username):
user = {'name': username, 'age': 23, 'gender': '保密'}
return JsonResponse(user)

查询字符串

查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。

  • 路由匹配:http://127.0.0.1:8000/goods/?page=1&num=10
1
2
3
urlpatterns = [
path('goods/', goodsList)
]
  • 视图实现
1
2
3
4
5
6
7
8
def goodsList(request):
query_dict = request.GET # 得到包含params参数的 query dict字典

page = query_dict.get('page', 1)
num = query_dict.get('num', 10)

return HttpResponse('当前第{}页, 每页{}条'.format(page, num))

请求体参数-表单数据

  • 路由匹配: http://127.0.0.1:8000/goods/, 此时通过 requset.POST 获取请求体中的 form-data数据,注意:请求方式必须是 POST
1
2
3
urlpatterns = [
path('goods/', goodsList)
]
  • 视图实现
1
2
3
4
5
6
7
def goodsList(request):
query_dict = request.POST # 得到包含form-data数据的django query dict字典

page = query_dict.get('page', 1)
num = query_dict.get('num', 10)

return HttpResponse('当前第{}页, 每页{}条'.format(page, num))

请求体参数-非表单数据

  • 路由匹配: http://127.0.0.1:8000/goods/, 此时通过 requset.body 获取请求体中的 json数据
1
2
3
urlpatterns = [    
path('goods/', goodsList)
]
  • 视图实现
1
2
3
4
5
6
7
def goodsList(request):  	
json_str = request.body # 获取请求体中的json内容
query_dict = json.loads(json_str) # 解析为python dict
print(query_dict)
page = query_dict.get('page', 1)
num = query_dict.get('num', 10)
return HttpResponse('当前第{}页, 每页{}条'.format(page, num))

Django query dict VS python dict

  • HttpRequest 对象中,属性 GETPOST 得到的都是 django.http.QueryDict 所创建的实例,这是一个 django 自定义的类似字典的类
  • 与python字典不同,用来处理同一个键带多个值的情况。
  • get():根据键获取值,如果一个键同时拥有多个值将获取最后一个值;如果键不存在则返回None值,可以设置默认值进行后续处理

    1
    dict.get('键',默认值)
  • getlist():根据键获取值,值以列表返回,可以获取指定键的所有值;如果键不存在则返回空列表[],可以设置默认值进行后续处理

    1
    dict.getlist('键',默认值)

请求头数据

  1. request.META.get("header key") 用于获取header的信息
  2. 注意的是header key必须增加前缀HTTP,同时大写,例如你的keyusername,那么应该写成:request.META.get("HTTP_USERNAME")
  3. 另外就是当你的header key中带有中横线,那么自动会被转成下划线,例如my-user的写成: request.META.get("HTTP_MY_USER")
  • 路由匹配: http://127.0.0.1:8000/goods/, 此时通过 requset.META 获取请求体中的 参数
1
2
3
urlpatterns = [    
path('goods/', goodsList)
]
  • 视图实现
1
2
3
4
5
def goodsList(request):  	
head_dict = request.META
page = head_dict.get('HTTP_PAGE', 1)
num = head_dict.get('HTTP_NUM', 10)
return HttpResponse('当前第{}页, 每页{}条'.format(page, num))

HttpRequest对象属性

  • request.user:获取当前用户对象

  • method:一个字符串,表示请求使用的HTTP方法,常用值包括:GETPOST

  • FILES:一个类似于字典的对象,包含所有的上传文件