一、视图函数介绍
视图就是应用中views.py中定义的函数,称为视图函数
def index(request):
return HttpResponse("hello world!")
1、视图的第一个参数必须为HttpRequest对象,还可能包含下参数如通过正则表达式组获取的位置参数、通过正则表达式组获得的关键字参数。
2、HttpRequest对象包含了请求的所有数据(请求头、请求体)
3、视图函数必须得返回一个HttpResponse对象或者其子类对象。
子对象: JsonResponse HttpResponseRedirect
4、视图负责接受Web请求HttpRequest,进行逻辑处理,返回Web响应HttpResponse给请求者
响应内容可以是HTML内容,404错误,重定向,json数据…
二、HTTPRequest对象(get请求与post请求)
网址中问号前边表示路由,问号后面表示查询字符串
http://127.0.0.1:8000/orders/getOrders/12345?name=zhangsan&age=18
路由:orders/getOrders/12345/
查询字符串:name=zhangsan&age=18
HttpRequest对象的属性GET、POST都是QueryDict类型的对象
2.1 url路径参数(前端向后端传递参数)
如请求:
http://127.0.0.1:8000/orders/getOrders/12345?name=zhangsan&age=18
url中,12345 要求是一个数字类型的变量。
在url中的变量参数。
在url路径中传递的参数
在请求实例方法中,使用关键字参数来接收
如:
路由配置
path("getOrders/<int:order_id>/",views.OrdersView.as_view()),
视图接收变量
def get(self,request,order_id):
print(request)
order_data_dic = {
'id': order_id,
'name': '电脑',
'price': '500¥'
}
变量名称在两处要保持一致。
2.2 get 请求传参
HttpRequest对象的属性GET、POST都是QueryDict类型的对象
get请求,有两种形式的传参。
2.3.1 url ?后面的key value键值对参数
如 http://www.xxx.com/?key1=value1&key2=value2
views视图函数中获取传参方式,使用request.GET获取:
1、request.GET返回QueryDict (用户在url传参数的整个数据体),类似于python中dict类型
2、想要获取请求中的具体某个字段:
- 方法get():根据键获取值
可以使用['key1']、get('key1'),会返回具体的值,如果有多个相同key的键值对,获取的是最后一个
3、getlist('key1'),获取相同key的多个值,返回list类型
- 方法getlist():根据键获取值,值以列表返回,可以获取指定键的所有值
举例:
1、视图函数,获取传参
def get_demo(request):
request_obj = request.GET
name = request_obj["name"]
age = request_obj.get("age")
json_data = {
"name":name,
"age":age,
"request_obj":request_obj
}
return JsonResponse(json_data)
2、配置路由
path('get_demo/',views.get_demo),
注意:
1、查询字符串不区分请求方式,如果客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。
2.3.3 get 请求传参为json
2.3 POST请求&请求体
HttpRequest对象的属性GET、POST都是QueryDict类型的对象。
请求体数据格式不固定,可以是表单类型字符串,可以是JSON字符串,可以是XML字符串,应区别对待。
可以发送请求体数据的请求方式有POST、PUT、PATCH、DELETE。
Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在settings.py文件中注释掉CSRF中间件,
#'django.middleware.csrf.CsrfViewMiddleware',
2.3.1 POST请求 表单类型 Form Data
前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回QueryDict对象。
1、创建post 视图函数,通过request.POST属性获取传参数
def post_test1(request):
if request.method == 'GET':
return HttpResponse("这是一个get请求")
elif request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
json_data = {
"name": name,
"age": age,
"response_obj": request.POST
}
return JsonResponse(json_data)
else:
return HttpResponse("这是一个其他类型的请求")
2、配置路由
path('post_test1/',views.post_test1)
3、创建post请求,请求体为Form表单
报错处理
1、 RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/orders/post_test2/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
客户端,在请求时,url 不是以/结尾的。必须以/结尾。
错误的url:http://127.0.0.1:8000/orders/post_test2
正确的url: http://127.0.0.1:8000/orders/post_test2/
2.3.2 POST请求 请求体为JSON
请求体为JSON或者XML,都属于非表单类型 Non-Form Data。
非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。
request.body返回bytes类型。
1、创建post 视图函数,通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。
def post_test2(request):
if request.method == 'POST':
# request.body 为<class 'bytes'>类型的json
request_json = request.body
# 将 bytes/str类型的json转成字典
request_dic = json.loads(request_json)
# 解析字典,取数据
name = request_dic.get("name")
age = request_dic.get("age")
return HttpResponse(f"我的名字是{name},今年{age}岁")
else:
return HttpResponse("这是一个其他类型的请求")
2、配置路由
path('post_test2/',views.post_test2),
3、创建 post 请求体为json的请求
其他:
1、json格式的字符串,与字典相互转换
json.loads 将json格式的字符串,转为字典
json.dumps 将字典,转成json格式的字符串
三、请求头
可以通过request.META属性获取请求头headers中的数据,request.META为字典类型。
四、HttpResponse
格式:
HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
a.第一个参数(响应体)必须为字符串类型
b.content_type可以指定响应头中的Content-Type参数
c.status可以指定响应状态码
json_str = json.dumps(project_data, ensure_ascii=False)
return HttpResponse(f"<h1>获取项目{pk}信息</h1>")
return HttpResponse(json_str, content_type='application/json', status=201)
六、JsonResponse
HttpResponse的子类
实现功能:
JsonResponse用于返回json数据(用户端接收的数据)
若要返回json数据,可以使用JsonResponse来构造响应对象,作用:
- 帮助我们将数据转换为json字符串
- 设置响应头Content-Type为application/json
服务端在组装JsonResponse数据时,可以传入字典类型的数据,也可以传入嵌套字典的列表)
字典类型的数据:
return JsonResponse(dict_data)
嵌套字典的列表:
必须设置safe=False。关掉安全模式
return JsonResponse(project_data_list, safe=False)
# c.第一个参数可以直接传递字典或者嵌套字典的列表
# d.默认添加content_type为application/json
# e.默认第一个参数只能为字典,如果为嵌套字典的列表,需要
return JsonResponse(project_data, json_dumps_params={'ensure_ascii': False}, status=201)
2.1 get请求
如 http://127.0.0.1:8000/orders/getOrders/12345?name=zhangsan&age=18
整个url中,url中的变量为 12345
传参为 name=zhangsan&age=18
三、视图类
使用视图类:
- 配置URLconf
- 在应用/views.py中定义视图
3.1 定义视图类
1、在views.py中,定义视图类。
2、必须继承View或者View子类
3、不同的请求方法有相应的方法进行对应。
GET -> get
POST -> post
PUT -> put
DELETE -> delete
PATCH -> patch
4、每一个处理请求的方法,必须得返回HttpResponse对象或者HttpResponse子类对象
5、每一个处理请求的方法,第二个参数必须为HttpRequest对象
class OrdersView(View):
# GET -> get 方法
def get(self,request,order_id):
order_data_dic = {
'id': order_id,
'name': '电脑',
'price': '500¥'
}
return JsonResponse(order_data_dic)
# POST -> post
def post(self,request,order_id):
return HttpResponse(f"{order_id}的post请求")
3.2 定义视图类的路由
样式:类视图.as_view()
path("getOrders/<int:order_id>/",views.OrdersView.as_view())
具体代码如下:
from django.urls import path
from . import views
urlpatterns = [
path('get/',views.get_order),
path('delete/',views.delete_order),
path('get_goods_info/<int:goods_id>/',views.get_goods_info),
# 定义定义类视图的路由条目
# 样式:类视图.as_view()
path("getOrders/<int:order_id>/",views.OrdersView.as_view())
]
其他:
在使用include函数定义路由时,可以使用namespace参数定义路由的命名空间,如
url(r'^',include('book.urls',namespace='book'))
命名空间表示,凡是book.urls中定义的路由,均属于namespace指明的book名下。
3.3 效果演示
postman get请求 视图类
http://127.0.0.1:8000/orders/getOrders/12345/
postman post请求 视图类
七、两种开发模式
# 1.前后端不分离的开发模式
# a.后端如果返回的是一个完整的html页面(页面中有填充数据)
# 2.前后端分离的开发模式
# a.后端如果返回的是数据(json、xml)
return JsonResponse(project_data_list, json_dumps_params={'ensure_ascii': False}, status=201, safe=False)
返回值
1、字典
2、嵌套字典的列表
1、字典
project_data = {
'id': 1,
'name': 'xxxx项目',
'leader': '潘潘达'
}
2、嵌套字典的列表
project_data_list = [
{
'id': 1,
'name': 'xxxx项目',
'leader': '潘潘达'
},
{
'id': 2,
'name': 'yyyy项目',
'leader': '多喝热水'
},
{
'id': 3,
'name': 'zzzz项目',
'leader': '不语'
}
]