一、README
线上教育平台:
接口得开发
1.建表models.py
2.引用admin
3.createsuperuser root root!2345
4.CC视频上传(账号),video.html显示
https://admin.bokecc.com/main.bo
http://127.0.0.1:8000/ccvideo/ (可看到上传得视频)
5.v1.3 - 接口: (与登录 课程 文章相关得接口)
1.查询所有课程
http://127.0.0.1:8000/api/v1/courses/
http://127.0.0.1:8000/api/v1/courses/?page=2 (全局设置得分页)
http://127.0.0.1:8000/api/v1/course/
http://127.0.0.1:8000/api/v1/course/?page=2 (自定义设置得分页)
2.查询课程详细
http://127.0.0.1:8000/api/v1/courses/1/ (简单得内容,继承)
http://127.0.0.1:8000/api/v1/course/1/ (自定制)
3.用户登录
http://127.0.0.1:8000/api/v1/auth/
- 返回随机字符串token
uid = str(uuid.uuid4())
- 库里update_or_create 新增或修改token
models.UserToken.objects.update_or_create(user=user_obj,defaults={'token':uid})
4.登录之后才能访问得页面,文章相关
http://127.0.0.1:8000/api/v1/articles/?page=2&token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
http://127.0.0.1:8000/api/v1/articles/2/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
# 不同得视图函数
http://127.0.0.1:8000/api/v1/article/?page=2&token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
http://127.0.0.1:8000/api/v1/article/2/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
- 认证组件
authentication_classes = [LuffyAuth, ]
- 验证从前端传来得token是否存在
token = request.query_params.get("token")
存在,返回元祖 return (obj.user.user,obj)
不存在,抛异常 raise AuthenticationFailed({'code':1001,'error':'认证失败'})
5.对文章评论,需要先登录,所以接口有登录认证
http://127.0.0.1:8000/api/v1/article/1/comment/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
{"content":"评论得内容"}
{"content":"评论得内容","pid":5}
6.对文章点赞,需要登录认证
http://127.0.0.1:8000/api/v1/article/1/agree/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
不需要传什么,文章得id随着url传过去了。
7.对文章收藏,需要登录认证
http://127.0.0.1:8000/api/v1/article/4/collect/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
不需要传什么,文章得id随着url传过去了。
delete请求:
取消对文章得收藏
6.v1.4 - 接口:(与购物车 相关得接口,需要登录认证)
方案一: 这种方式不好,每次都要全部拿出来,修改,在放进去
http://127.0.0.1:8000/api/v1/shopping/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
购物车中添加一条数据 {"courseid":2,"policyid":3}
get请求:
查看自己购物车中的所有数据 ...
delete请求:
删除购物车中的数据 {"delete_ids":[1,2]}
put请求:
更新价格策略 ... {"courseid":2,"policyid":3}
方案二:数据结构得设计好坏,直接影响了代码实现得复杂度;
http://127.0.0.1:8000/api/v1/shoppingcart/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
{"courseid":2,"policyid":3}
delete请求:
{"courseids":[1,2]}
patch请求:
{"courseid":2,"policyid":3}
get请求:
...
7.v1.5 - 接口:(与支付中心 相关得接口,需要登录认证)
方式一:这种方式不好,查询数据时,每次都要去数据库查询,优惠劵,逻辑还有点问题,查看版本二.
http://127.0.0.1:8000/api/v1/payment/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
将购物车得课程,加入到支付中心
{"courseids":[1,2]}
get请求:
获取支付中心得数据
。。。
patch请求:
修改课程得优惠券
{"courseid":1,"couponid":1}
方式二:
http://127.0.0.1:8000/api/v1/paymentview/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
将购物车得课程,加入到支付中心
{"courseids":[1,2]}
get请求:
获取支付中心得数据
。。。
patch请求:
修改课程得优惠券,全局得优惠劵
{"courseid":1,"couponid":1,"gcouponid":5}
8.v1.6 - 接口:(生成订单得接口,需要登录认证)
http://127.0.0.1:8000/api/v1/order/?token=22abe8c6-717a-4b1b-a164-84d4c18aea5b
post请求:
将redis中,支付中心得数据,生成订单,存到数据库中
{"balance":1000,"money":245} # balance用户得抵扣得贝里数,money是实付金额
对于用户,前端传来得数据,后台入库之前,一定要做校验,验证合法性。
二、v1.3 - 知识点 - 登录、课程、文章相关得接口
版本 分页
REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer','rest_framework.renderers.BrowsableAPIRenderer'], 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本 'VERSION_PARAM': 'version', # 参数 'DEFAULT_VERSION': 'v1', # 默认版本 "DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination", "PAGE_SIZE":1, }
from rest_framework.pagination import PageNumberPagination class MyPageNumberPagination(PageNumberPagination): page_size = 1 page_query_param = "page"
urls.py
url(r'^api/(?P<version>\w+)/',include('api.urls')), ------------------------------------------------- from django.conf.urls import url, include from rest_framework import routers from api.views import course, account, article routers = routers.DefaultRouter() routers.register("courses", course.CourseViewSet) routers.register("articles", article.ArticelViewSet) urlpatterns = [ url(r'^auth/$', account.AuthView.as_view()), url(r'^', include(routers.urls)), url(r'^course/$', course.CourseView.as_view({"get": "list"})), url(r'^course/(?P<pk>\d+)/$', course.CourseView.as_view({"get": "retrieve"})), url(r'^article/$', article.ArticleView.as_view({"get": "list"})), url(r'^article/(?P<pk>\d+)/$', article.ArticleView.as_view({"get": "retrieve"})), url(r'^article/(?P<pk>\d+)/comment/$', article.CommentView.as_view()), # 对文章评论 url(r'^article/(?P<pk>\d+)/agree/$', article.AgreeView.as_view()), # 对文章点赞 url(r'^article/(?P<pk>\d+)/collect/$', article.CollectView.as_view()), # 对文章收藏、取消(post delete) ]
中间件 - 跨域处理 cors.py
from django.utils.deprecation import MiddlewareMixin class CORSMiddleware(MiddlewareMixin): def process_response(self, request, response): # 允许你的域名来访问 response['Access-Control-Allow-Origin'] = "*" if request.method == 'OPTIONS': # 允许你携带 Content-Type 请求头 不能写* response['Access-Control-Allow-Headers'] = 'Content-Type' # 允许你发送 DELETE PUT请求 response['Access-Control-Allow-Methods'] = 'DELETE,PUT' return response
课程 文章 登录 (相关得接口)
涉及到
分页
视图 ViewSetMinin ModelViewSet APIView
序列化
认证 authentication_classes = [LuffyAuth, ]
事务 with transaction.atomic(): ... ...
异常 try ... except 异常捕获
# -*- coding:utf-8 -*- from rest_framework import mixins from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.viewsets import ViewSetMixin, GenericViewSet from utils.response import BaseResponse from api.models import Course, CourseDetail from utils.paginator import MyPageNumberPagination from api.serializers.course import CourseSerializers, CourseDetailSerializers class CourseView(ViewSetMixin, APIView): """ 课程相关得接口 """ def list(self, request, *args, **kwargs): """ 查看全部课程 :param request: :param args: :param kwargs: :return: """ ret = BaseResponse() pnp = MyPageNumberPagination() try: course_list = Course.objects.all() courses_page = pnp.paginate_queryset(course_list, request, self) ser = CourseSerializers(courses_page, many=True) ret.data = ser.data except Exception as e: ret.code = "1001" ret.error = "获取课程失败" return pnp.get_paginated_response(ret.dict) def retrieve(self, request, *args, **kwargs): """ 查看单条课程 :param request: :param args: :param kwargs: :return: """ ret = BaseResponse() try: pk = kwargs.get("pk") course_obj = CourseDetail.objects.filter(course_id=pk).first() ser = CourseDetailSerializers(instance=course_obj, many=False) ret.data = ser.data except Exception as e: ret.code = 1001 ret.data = "获取课程失败" return Response(ret.dict) class CourseViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet): """ 查看全部、单条课程 """ queryset = Course.objects.all() serializer_class = CourseSerializers def video(request): """ 播放视频 """ return render(request, 'video.html')