类视图
视图:是一个接收请求,处理请求,返回响应的一个可被调用的对象,视图有函数视图,也要类视图
函数视图:以函数的形式定义视图,代码的可读性比较差,代码复用性差,如果需要处理多种请求(get,post,put等)的时候,需要加多个if 或者写多个视图。
类视图:以类定义的视图,请求方式:get,post,delete,put,类视图分别定义方法处理不同的请求。
类视图的定义
from django.views import View
class GoodsView(View):
# 处理get请求
def get(self.request):
result = {"methods":"get请求"}
return JsonResponse(result)
# 处理post请求
def post(self.request):
result = {"methods": "post请求"}
return JsonResponse(result)
# 处理put请求
def put(self.request):
result = {"methods": "put请求"}
return JsonResponse(result)
# 处理delete请求
def delete(self.request):
result = {"methods": "delete请求"}
return JsonResponse(result)
路由
为什么能够将具体的请求方式分配给相应的方法处理?
因为路由中,类视图的名字后面有,as_view() 方法,由 as_view(封装了disoatch 方法) 方法将具体的请求方式的请求,转发到相对应的方法中处理。
实现get请求
需求:获取全部的商品信息,如果传递id,获取指定的商品信息
def get(self.request):
id = request.GET.get('id')
if id:
# 查找对应id的数据
goods = Goods.objects.get(id=id)
data = {
"goods_number": goods.goods_number,
"goods_name": goods.goods_name,
"goods_price": goods.goods_price,
"goods_count": goods.goods_count,
"goods_location": goods.goods_location,
"goods_safe_data": goods.goods_safe_data,
"goods_pro_time": goods.goods_pro_time,
"goods_status": goods.goods_status,
}
else:
# 返回全部的商品信息
goods = Goods.objects.all()
data = []
for one in goods:
data.append({
"goods_number": one.goods_number,
"goods_name": one.goods_name,
"goods_price": one.goods_price,
"goods_count": one.goods_count,
"goods_location": one.goods_location,
"goods_safe_data": one.goods_safe_data,
"goods_pro_time": one.goods_pro_time,
"goods_status": one.goods_status,
})
result = {"methods":"get请 求","data":data,"version":"v1"}
return JsonResponse(result)
定义统一的返回结构
def __init__(self):
super(GoodsView,self).__init__()
self.result = {
"methods":'get请求',
"data":'',
"version":'v1'
}
csrf解决
-
可以注释掉 csrf 中间件
-
将制定的类视图避免 csrf 的校验
-
发送请求的时候,传递 csrf_token
- ajax 发送post请求,构架数据字典“csrfmiddlewaretoken”=“value”
restful
restful 是一种接口风格
类名定义或者是路由定义的名字,不能出现动词
django 开发restful 不方便,drf框架,Django REST framework
-
安装
代码:pip install djangorestframework
代码:pip install django-filter
-
配置
常识:下载安装好的django组件,都是以app 的形式存在的,所以需要注册
- 编写视图
from rest_framework import viewsets
from .serializer import GoodsSerializer
class GoodsViewsSet(viewsets.ModelViewSet):
queryset = Goods.objects.all() ## 固定的写法
serializer_class = GoodsSerializer ## 过滤器
- 编写过滤器
from rest_framework import serializers
from .models import *
class GoodsSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Goods
fields = [
"id",
"goods_number",
"goods_name",
"goods_price",
"goods_count",
"goods_location",
"goods_safe_data",
"goods_pro_time",
"goods_status",
] ## 将来restful 要返回的字段
- 路由
动静分离
只提供数据的接口,视图不在返回页面,而是只提供数据,可以增加视图的可重用性
需求:根据上架下架的状态,获取商品信息
视图:
def goods_list_api(request,type,page=1):
# type = 0,获取下架商品的信息
# type = 0,获取上架商品的信息
goods = Goods.objects.filter(goods_status = int(type)).order_by("-goods_number")
goods_obj = Paginator(goods,10) ## 每页10条
goods_list = goods_obj.page(page)
res = []
for one in goods_list:
res.append({
"goods_number":one.goods_number,
"goods_name":one.goods_name,
"goods_price":one.goods_price,
"goods_count":one.goods_count,
"goods_location":one.goods_location,
"goods_safe_data":one.goods_safe_data,
"goods_pro_time":one.goods_pro_time,
"goods_status":one.goods_status,
})
result = {
"page_range":list(goods_obj.page_range),
"data":res,
"page":page,
}
return JsonResponse(result)
路由:
模板:通过发送请求,携带参数,获取数据,并进行渲染
<body>
<div id="content">
</div>
<script>
// 写 ajax 发送请求 获取数据 将数据 渲染到指定的 div
$.ajax({
url:"http://127.0.0.1:8000/goods_list_api/1/1/",
type:"get",
data:"",
success:function (data) {
console.log(data.data)
for (var i in data.data){
console.log(data.data[i]["goods_name"])
var idata = "<p>" + data.data[i] ["goods_name"] + "</p>"
$("#content").append(idata)
}
},
error:function (data) {
console.log(data)
}
})
</script>
</body>
</html>