标签:请求 des 对象 fun pen error: 数组 doc 前后端分离
本章内容;
1. FBV与CBV
FBV: Function Base View
CBV:Class Base View
示例:
from django.shortcuts import render, HttpResponse from django.http import JsonResponse # Create your views here. def index(request): if request.method == "POST": print(request.POST) # 修改数据库 return HttpResponse("OK") return render(request, "index.html") # CBV from django import views class Index(views.View): def get(self, request): return render(request, ‘index.html‘) def post(self, request): print(request.POST) return HttpResponse("OK") # def index2(request): # if request.method == "GET": # return render(request, "index.html") # print(request.POST) # # 修改数据库 # return JsonResponse("OK") def ajax(request): return JsonResponse({"code": 0})
注意事项:
1.CBV定义一定要继承django.views.view
2. 注册路由的时候要写 类名.as_view()
3.具体原理是:dispatch()方法 中利用反射 找到每个请求执行
1 from django import views 2 3 4 class Index(views.View): 5 def get(self, request): 6 return render(request, ‘index.html‘) 7 8 def post(self, request): 9 print(request.POST) 10 return HttpResponse("OK")
状态码
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) 204 NO CONTENT - [DELETE]:用户删除数据成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
错误处理,状态码是4xx时,应返回错误信息,error当做key。
{ error: "Invalid API key" }
返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组) GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 PATCH /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档
Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
1
2
3
4
5
6
|
{ "link" : { "rel" : "collection https://www.example.com/zoos" , "href" : "https://api.example.com/zoos" , "title" : "List of zoos" , "type" : "application/vnd.yourformat+json" }} |
路由系统:
1
2
3
|
urlpatterns = [ url(r ‘^users‘ , Users.as_view()), ] |
CBV视图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
from django.views import View from django.http import JsonResponse class Users(View): def get( self , request, * args, * * kwargs): result = { ‘status‘ : True , ‘data‘ : ‘response data‘ } return JsonResponse(result, status = 200 ) def post( self , request, * args, * * kwargs): result = { ‘status‘ : True , ‘data‘ : ‘response data‘ } return JsonResponse(result, status = 200 )
|
实验案例:新闻系统
实现方式一:
1 from django.db import models 2 3 # Create your models here. 4 5 6 # 文章表 7 class Article(models.Model): 8 title = models.CharField(max_length=32) 9 # 文章发布时间 10 # auto_now每次更新的时候会把当前时间保存 11 create_time = models.DateField(auto_now_add=True) 12 # auto_now_add 第一次创建的时候把当前时间保存 13 update_time = models.DateField(auto_now=True) 14 # 文章的类型 15 type = models.SmallIntegerField( 16 choices=((1, "原创"), (2, "转载")), 17 default=1 18 ) 19 # 来源 20 school = models.ForeignKey(to=‘School‘, on_delete=models.CASCADE) 21 # 标签 22 tag = models.ManyToManyField(to=‘Tag‘) 23 24 25 # 文章来源表 26 class School(models.Model): 27 name = models.CharField(max_length=16) 28 29 30 # 文章标签表 31 class Tag(models.Model): 32 name = models.CharField(max_length=16)
执行命令:
migrate makemigrations
插入数据库数据
以上有了数据信息,然后进行json API接口的方式展示
1 from django.contrib import admin 2 from django.urls import path 3 from app01 import views 4 5 urlpatterns = [ 6 path(‘admin/‘, admin.site.urls), 7 path(‘article_list/‘,views.article_list), 8 ]
from django.shortcuts import render,HttpResponse from app01 import models import json # Create your views here. def article_list(request): #去数据库查询所有的文章数据 quest_set = models.Article.objects.all().values("id","title") #values是字典,values_list是列表 #序列化成json格式 data = json.dumps(list(quest_set),ensure_ascii=False) #返回 return HttpResponse(data)
注意:json只支持7种数据类型,ORM查询出来的结果为QuerySet类型,它是不支持的。
日期对象也是不支持的,需要转换为字符串。
启动django项目,访问URL: http://127.0.0.1/article_list/,因此每一个时间,都要转换为字符串,太麻烦了。
转换方式:
1 from django.shortcuts import render,HttpResponse 2 from app01 import models 3 import json 4 5 # Create your views here. 6 def article_list(request): 7 #去数据库查询所有的文章数据 8 quest_set = models.Article.objects.all().values("id","title","create_time") #values是字典,values_list是列表 9 #序列化成json格式 10 11 #1.先把时间对象转换成字符串格式 12 for i in quest_set: 13 i["create_time"] = i["create_time"].strftime(‘%Y-%m-%d‘) 14 15 data = json.dumps(list(quest_set), ensure_ascii=False) 16 #返回 17 return HttpResponse(data)
JsonResponse 对象:
class JsonResponse
(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None,**kwargs)
这个类是HttpRespon的子类,它主要和父类的区别在于:
1 from django.shortcuts import render,HttpResponse 2 from django.http import JsonResponse 3 from app01 import models 4 import json 5 6 # Create your views here. 7 #第二种方式 8 def article_list(request): 9 #去数据库查询所有的文章数据,返回queryset,每一个元素都是字典 10 query_set = models.Article.objects.all().values("id","title","create_time","type","school") 11 print(query_set) 12 for i in query_set: 13 print(i) 14 15 #学校对象 16 school_obj = models.School.objects.filter(id=i[‘school‘]).first() 17 #学校id 18 id = school_obj.id 19 #学校的名字 20 name = school_obj.name 21 #修改字典,key为school的值 22 i[‘school‘] = {"id":id,"name":name} 23 24 #返回json对象,safe=False表示任何能转换为json格式的对象 25 return JsonResponse(list(query_set),safe=False)
查看JsonResponse源代码
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(JsonResponse, self).__init__(content=data, **kwargs)
注意:从上面的代码中,可以看出。针对查询对应的学校信息,使用了for循环。它是一个外键字段,
那如果再查询一个外键字段呢?再来一个for循环?代码太冗长了!
serializer 允许复杂数据(比如 querysets 和 model 实例)转换成python数据类型,然后可以更容易的转换成 json 或 xml 等。同时,serializer也提供了反序列化功能,允许解析数据转换成复杂数据类型。
中文文档链接:
https://q1mi.github.io/Django-REST-framework-documentation/api-guide/serializers_zh/
class DBG(serializers.Serializer): # 声明序列化器 id = serializers.IntegerField() title = serializers.CharField() create_time = serializers.DateField() type = serializers.IntegerField() school = serializers.CharField(source="school.name")
注意:source = "school.name" 表示school表中的name字段
可以使用它来序列化和反序化与DBG对象相应的数据。
申明一个序列化看起来非常像申明一个form。我们之前学习form组件时,将需要的字段类型都指定好了!
标签:请求 des 对象 fun pen error: 数组 doc 前后端分离
原文地址:https://www.cnblogs.com/haowen980/p/9398510.html