目录javascript
目录结构:html
settings.py
文件# 下载 处理跨域问题的app: pip install django-cors-headers
# 注册app: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'api.apps.ApiConfig', 'corsheaders' # 注册app ]
# 注册中间件: MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 必须放在第一个位置 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
# corsheaders配置项: CORS_ORIGIN_ALLOW_ALL = True # 容许全部人 跨域请求 个人服务端
api/models.py
文件项目表结构设计前端
CourseCategory
Course
CourseDetail
Teacher
PricePolicy
CourseChapter
CourseSection
OftenAskedQuestion
Coupon
CouponRecord
Order
OrderDetail
UserInfo
-- 继承AbstractUser
Token
表注意: 在settings.py
文件中添加配置项vue
# 告诉Django用我本身写的 UserInfo表 代替内置的 User表 AUTH_USER_MODEL = 'api.UserInfo' # app名.表名
api/admin.py
文件from django.contrib import admin from api import models admin.site.register(models.Course) # 课程表 admin.site.register(models.CourseDetail) # 课程详情表 admin.site.register(models.CourseCategory) # 课程分类表 admin.site.register(models.CourseChapter) # 课程章节表
python manage.py createsuperuser
admin
页面, 对以上四个表的数据进行修改urls.py
文件路由分发:java
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^api/', include('api.urls')), ]
api/urls.py
文件路由匹配:python
from django.conf.urls import url from api.views import course as course_view from api.views import login as login_view urlpatterns = [ # 课程展现 url(r'courses/$', course_view.CourseListView.as_view()), ]
api/views/course.py
文件from rest_framework.generics import ListAPIView from api import models from api.serializers.course import CourseModelSerializer from rest_framework.response import Response class CourseListView(ListAPIView): queryset = models.Course.objects.all() serializer_class = CourseModelSerializer def get(self, request, *args, **kwargs): """"重写ListAPIView的get方法""" pass
因为是先后端分离, 对于视图函数CourseListView
, 咱们要返回一个合适的接口, 所以,ios
必须重写父类的get
方法. 这个时候, 就须要看一看ListAPIView
的源码了.django
ListAPIView
源码:list
方法:如今, 咱们回归到原本的问题上, 咱们要重写ListAPIView
的get方法, 从而返回一个合适的接口, 可是, 因为ListAPIView
自己也有一些功能, 若是咱们直接重写, 势必会对其余功能形成影响. 咱们的解决办法是: 将list
方法功能相关的代码直接粘贴到咱们重写的get方法里, 而后在不改动这些代码的前提下, 进行咱们本身的处理(主要是处理返回值, 即接口).axios
course.py
文件:后端
from rest_framework.generics import ListAPIView from api import models from api.serializers.course import CourseModelSerializer from rest_framework.response import Response class CourseListView(ListAPIView): queryset = models.Course.objects.all() serializer_class = CourseModelSerializer def get(self, request, *args, **kwargs): try: #### list源码 #### queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) #### list源码 #### data = serializer.data except Exception as e: code = 1 msg = str(e) res = {'code': code, 'data': data, 'msg': msg} return Response(res)
上面代码中, res这个字典就是咱们与前端交互的接口. 因为每次都要本身硬编码该字典内部的key和value, 这样的作法是不可靠且极为繁琐的, 所以, 咱们考虑将它们封装为一个对象. 以下所示:
utils/response.py
文件class BaseResponse(object): def __init__(self): self.code = 1000 # 状态码 self.data = None # 具体数据 self.msg = '' # 提示信息 @property def dict(self): return self.__dict__ # __dict__把类的属性以字典的形式返回
course.py
文件: 改进版本
from rest_framework.generics import ListAPIView from api import models from api.serializers.course import CourseModelSerializer from rest_framework.response import Response from utils.response import BaseResponse # 引入自定义工具类 class CourseListView(ListAPIView): queryset = models.Course.objects.all() serializer_class = CourseModelSerializer def get(self, request, *args, **kwargs): res_obj = BaseResponse() # 实例化自定义工具类 try: #### list源码 #### queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) #### list源码 #### res_obj.data = serializer.data # 赋值给data属性 except Exception as e: res_obj.code = 1 # 赋值给code属性 res_obj.msg = str(e) # 赋值给msg属性 return Response(res_obj.dict) # 经过dict方法就能够拿到全部属性组成的字典
api/serializers/course.py
文件自定义序列化类CourseModelSerializer
:
from rest_framework import serializers from api import models class CourseModelSerializer(serializers.ModelSerializer): class Meta: model = models.Course fields = "__all__"
src/main.js
文件配置根URL:
// 导入Axios import Axios from 'axios' Axios.defaults.baseURL = 'http://127.0.0.1:8001/api'; Vue.prototype.$axios = Axios;
src/router.js
文件路由匹配:
import Course from './views/Course.vue' Vue.use(Router); export default new Router({ routes: [ { path: '/course', name: 'course', component: Course, }, ] })
src/views/Course.vue
文件自定义组件Course.vue
:
getCourseList() { this.$axios.get('/courses/') // 修改路径,要与后端的路径信息相匹配 .then((res) => { // res 是接收到的后段的返回值 // console.log(res); if (res.data.code === 1000) { // code状态码 this.courseList = res.data.data; // data具体数据信息 // 去掉加载动画 this.loading = false } }) },