1.restful API 规范
| RESTful是目前最流行的API设计规范,它是用于Web数据接口的设计。从字面可以看出,他是Rest式的接口,所以我们先了解下什么是Rest。 |
| |
| REST与技术无关,它代表的是一种软件架构风格,REST它是 Representational State Transfer的简称,中文的含义是: "表征状态转移" 或 "表现层状态转化"。 |
| |
| 它是基于HTTP、URI、XML、JSON等标准和协议,支持轻量级、跨平台、跨语言的架构设计。 |
1.1数据的安全性
| 一般都采用HTTPS协议进行传输,提高了数据交互过程中的安全性 |
1.2接口中带有API标识
| https://api.baidu.com |
| https://www.baidu.com/api |
1.3 多数据版本共存
| 在url链接中标识数据版本 |
| https://api.baidu.com/v1 |
| https://api.baidu.com/v2 |
1.4数据即是资源,均使用名词(可复数)
| 一般都是完成前后台数据的交互,交互的数据我们称之为资源 |
| https://api.baidu.com/users |
| https://api.baidu.com/books |
| 注:一般提倡用资源的复数形式,在url链接中奖励不要出现操作资源的动词 |
1.5资源操作由请求方式决定(method)
| 操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作 |
| https://api.baidu.com/books - get请求:获取所有书 |
| https://api.baidu.com/books/1 - get请求:获取主键为1的书 |
| https://api.baidu.com/books - post请求:新增一本书书 |
| https://api.baidu.com/books/1 - put请求:整体修改主键为1的书 |
| https://api.baidu.com/books/1 - patch请求:局部修改主键为1的书 |
| https://api.baidu.com/books/1 - delete请求:删除主键为1的书 |
1.6过滤,通过在url上传参的形式传递搜索条件
| https://api.baidu.com/books?name=红&price=99 |
1.7响应状态码
| -http响应状态码:1xx:请求正在处理,2xx:成功响应,3xx:重定向,4xx:客户端错误,5xx:服务端错误 |
| -https://blog.csdn.net/li_chunlong/article/details/120787872 |
| -公司内部规定的响应状态码,放在响应体中 |
| {code:0} |
1.8错误处理,应返回错误信息,error当做key
1.9返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
| GET 获取所有数据:返回资源对象的列表(数组)[{name:红楼梦,price:99},{name:红楼梦,price:99},{name:红楼梦,price:99}] |
| GET 单个对象:返回单个资源对象:{name:红楼梦,price:99} |
| POST 新增对象:返回新生成的资源对象:{name:西游记,price:99} |
| PUT 修改对象:返回完整的资源对象 :{name:西游记,price:100} |
| DELETE 删除:返回一个空文档 |
1.10 需要url请求的资源需要访问资源的请求链接
| |
| { |
| "status": 0, |
| "msg": "ok", |
| "results":[ |
| { |
| "name":"肯德基(罗餐厅)", |
| "img": "https://image.baidu.com/kfc/001.png" |
| } |
| ] |
| } |
2 序列化与反序列化
| api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把数据转换格式,序列化可以分两个阶段: |
| 序列化: 把我们识别的数据转换成指定的格式提供给别人 |
| 字典,列表------》json格式存到文件中了 |
| 例如:我们在django中获取到的数据默认是模型对象,但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人 |
| read |
| 反序列化:把别人提供的数据转换/还原成我们需要的格式。 |
| 例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中。 |
| write |
3 基于django原生编写5个接口
url
| from django.contrib import admin |
| from django.urls import path |
| from django.contrib import admin |
| from rest_framework.routers import SimpleRouter |
| from app01 import views |
| |
| |
| urlpatterns = [ |
| path('admin/', admin.site.urls), |
| path('api/v1/books/',views.BookView.as_view()), |
| path('api/v1/books/<int:pk>/',views.BookDetailView.as_view()) |
| ] |
| |
models
| from django.db import models |
| |
| |
| from django.db import models |
| |
| class Book(models.Model): |
| name=models.CharField(max_length=32) |
| price=models.CharField(max_length=32) |
| publish=models.CharField(max_length=32) |
views
| import json |
| |
| from django.shortcuts import render |
| from django.http import JsonResponse |
| |
| |
| from .models import Book |
| |
| |
| |
| |
| |
| |
| from django.views import View |
| class BookView(View): |
| def get(self,request): |
| books=Book.objects.all() |
| book_list=[] |
| for book in books: |
| book_list.append({'name':book.name,'price':book.price,'publish':book.publish}) |
| return JsonResponse(book_list,safe=False,json_dumps_params={'ensure_ascii': False}) |
| |
| |
| |
| |
| |
| |
| |
| |
| def post(self,request): |
| |
| |
| |
| |
| s1=json.loads(request.body) |
| name=s1.get('name') |
| price=s1.get('price') |
| publish=s1.get('publish') |
| book=Book.objects.create(name=name,price=price,publish=publish) |
| return JsonResponse({'name': book.name, 'price': book.price, 'publish': book.publish}) |
| |
| class BookDetailView(View): |
| def get(self,request,pk): |
| book=Book.objects.filter(pk=pk).first() |
| return JsonResponse({"id":book.pk,'price': book.price, 'publish': book.publish}) |
| def put(self,request,pk): |
| book=Book.objects.filter(pk=pk).first() |
| back_dict=json.loads(request.body) |
| book.name=back_dict.get('name') |
| book.price=back_dict.get('price') |
| book.publish=back_dict.get('publish') |
| book.save() |
| return JsonResponse({'id': book.pk, 'price': book.price, 'publish': book.publish}) |
| def delete(self,request,pk): |
| Book.objects.filter(pk=pk).delete() |
| return JsonResponse(data={}) |
4 drf介绍和快速使用
| |
| |
| |
| |
| pip3 install djangorestframework -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/ |
| |
| |
| |
| from .serializer import BookSerializer |
| from rest_framework.viewsets import ModelViewSet |
| class BookView(ModelViewSet): |
| queryset = Book.objects.all() |
| serializer_class = BookSerializer |
| |
| |
| from rest_framework import serializers |
| from .models import Book |
| class BookSerializer(serializers.ModelSerializer): |
| class Meta: |
| model = Book |
| fields = '__all__' |
| |
| |
| from rest_framework.routers import SimpleRouter |
| router = SimpleRouter() |
| router.register('books', views.BookView, 'books') |
| |
| urlpatterns = [ |
| path('admin/', admin.site.urls), |
| ] |
| |
| urlpatterns += router.urls |
5 cbv源码分析
| |
| -当请求来了,匹配成功会执行,views.BookView.as_view()(request) |
| -views.BookView.as_view()执行结果是View的类方法as_view返回的结果是内层函数view,是个函数内层地址 |
| -本身请求来了,匹配成功,会执行view(request) |
| def view(request, *args, **kwargs): |
| return self.dispatch(request, *args, **kwargs) |
| |
| -self.dispatch View类的方法 |
| def dispatch(self, request, *args, **kwargs): |
| |
| if request.method.lower() in self.http_method_names: |
| |
| |
| handler = getattr(self, request.method.lower(), self.http_method_not_allowed) |
| else: |
| handler = self.http_method_not_allowed |
| |
| return handler(request, *args, **kwargs) |
1、先找BookView中as_view方法,没有找到,找父类View,找到View中的as_view执行,返回view
2、执行View中的view,返回结果self.dispatch,self为自定义的类的对象,自定义类中无dispatch方法就执行View中的dispatch
3、执行View中的dispatch,利用反射执行对应的请求函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?