Djnaog 之路飞学城前后端分离/api接口
路飞学城项目之前后端分离
前后端故名思议就是前端和后端分离开来,一个人写前端,一个人写后端.
前后端都是要基于restful协议进行的.那么什么是resful协议?
后端主要是写接口,所谓的接口就是url,前端用ajax技术发送请求给后端,向后端拿想要的数据
而后端只需要返回json数据即可.
用Django的restframework框架写API接口
提供简单的model
model
class Course(models.Model): '''课程表''' Course_level=( (0,'低级'), (1,'中级'), (2,'高级'), ) title=models.CharField(max_length=32,verbose_name='课程') img_src=models.CharField(max_length=64,default='static/images/logo.png') level=models.PositiveIntegerField(choices=Course_level,default=1) def __str__(self): return self.title class CourseDetail(models.Model): '''课程详细表''' name=models.CharField(max_length=255,verbose_name='口号') course=models.OneToOneField('Course',on_delete=models.CASCADE,related_name='c') why_study=models.TextField(verbose_name='为什么学习') recommend_course=models.ManyToManyField('Course',related_name='course_recomend',verbose_name='推荐课程',null=True,blank=True) def __str__(self): return self.name class Chapter(models.Model): '''章节''' number_chapter=models.IntegerField(verbose_name='第几章节') title=models.CharField(max_length=32,verbose_name='章节名称') chapter_course=models.ForeignKey('Course',on_delete=models.CASCADE) def __str__(self): return '第%s章节%s'%(self.number_chapter,self.title)
里面涉及了多对多,一对多,还有choice字段,基本涵盖了大多数字段的类型
url:
urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^api/(?P<version>\w+)/', include('api.urls')), ]
urlpatterns = [ path('course/',course.CourseView.as_view({'get':'list'})), re_path(r'^course/(?P<pk>\d+)/$',course.CourseView.as_view({'get':'retrieve', 'put':'update', 'delete':'destroy'})), ]
获取所有的课程表
view:
class CourseView(ViewSetMixin,APIView): def list(self,request,*args,**kwargs): '''查看课程列表''' ret={'code':1000,'data':None} try: queryset=models.Course.objects.all() ser=apiserializer.CourseModelSerializer(instance=queryset,many=True) ret['data']=ser.data except Exception as e: ret['code']=1001 ret['data']='获取数据错误' return Response(ret)
再来看序列化组件:
class CourseModelSerializer(ModelSerializer): '''Course表的序列化''' level=serializers.CharField(source='get_level_display') class Meta: model=models.Course fields=['id','title','img_src','level'] # 不建议用,因为有太多的无用信息 #depth=1 #0-10
自定义字段需要写在fields里
get_level_display是取choice的中文名称
自定义字段后面会详细说明
前端vue接收数据:
main.js:

import axios from 'axios'
import Vuex from 'vuex'
Vue.use(Vuex);
Vue.prototype.$axios = axios;
const store = new Vuex.Store({
state: {
allCourseList:[],
//这里面的状态跟每个组件的数据属性有关系
},
mutations: {
GETCOURSELIST(state,newValue){
state.allCourseList =newValue;
},
},
actions:{
GetCourseList(context,){
axios.request({
url:'http://127.0.0.1:8000/api/v2/course/',
method:'GET',
}).then(function(ret){
context.commit('GETCOURSELIST',ret.data.data)
}).catch(function(ret){
})
},
},
});
在初始化course组件的时候发送请求接收数据:
Vcourse.vue

mounted(){
this.$store.dispatch('GetCourseList');
}
在VcourseList.vue里获取到state里的数据然后传给子vue

<template> <ul> <VcourseItem v-for="item in GetAllList" :data="item"></VcourseItem> </ul> </template> <script> import VcourseItem from './VcourseItem' export default { name: "VcourseList", data() { return {} }, components:{ VcourseItem, }, computed:{ GetAllList(){ return this.$store.state.allCourseList }, } } </script> <style scoped> </style>
VcourseItem.vue

<template> <li> <router-link :to="{name:'detail',params:{id:data.id}}"> <img :src="'/'+data.img_src" alt=""> <div>{{data.title}}</div> </router-link> <div>难度{{data.level}}</div> </li> </template> <script> export default { name: "VcourseItem", data() { return { } }, props:{ data:Object, }, } </script> <style scoped> </style>
props
这里需要说明的是,父vue传数据到子vue,进行验证
props:{
data:Object}
props所有的数据类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object
}
可以看到vue里有跳转到查看详细的router-link
<router-link :to="{name:'detail',params:{id:data.id}}"> { path: '/detail/:id', name: 'detail', component: Vdetail },
如何序列化有外键的字段
view:
def retrieve(self,request,*args,**kwargs): '''查看课程详细''' ret={'code':1000,'data':None} try: pk=kwargs.get('pk') obj=models.CourseDetail.objects.filter(course_id=pk).first() ser=apiserializer.CourseDetailModelSerializer(instance=obj) ret['data']=ser.data except Exception as e: ret['code'] = 1001 ret['error'] = '获取数据错误' return Response(ret)
具体操作
前面介绍了前后端分离的整个过程,那么这里主要介绍对 对多对,一对多,反向查询的序列化
- 对于正向查询的外键:
title=serializers.CharField(source='course.title')我们只需要用序列化cource字段就可以进行跨表获取数据
- 对于多对多字段::
recommend_course=serializers.SerializerMethodField()首先需要实例化serializers.SerializerMethodField()类
def get_recommend_course(self, obj): #get_对象名(recommend_course)
-
queryset=obj.recommend_course.all() return [{'title':row.title,'level':row.get_level_display()} for row in queryset]
只要return回想要的数据即可.这里的obj是view传递的obj
*对于反向查询的一对多字段:
chapter=serializers.SerializerMethodField()
def get_chapter(self,obj):
queryset=obj.course.chapter_set.all()
return [{'num':obj.number_chapter,'chater':obj.title} for obj in queryset] 与上述的思路一样,这里不做赘述
class CourseDetailModelSerializer(ModelSerializer): '''CourseDetail''' title=serializers.CharField(source='course.title') img=serializers.CharField(source='course.img_src') level=serializers.CharField(source='course.get_level_display') recommend_course=serializers.SerializerMethodField() chapter=serializers.SerializerMethodField() def get_recommend_course(self, obj): queryset=obj.recommend_course.all() return [{'title':row.title,'level':row.get_level_display()} for row in queryset] def get_chapter(self,obj): queryset=obj.course.chapter_set.all() return [{'num':obj.number_chapter,'chater':obj.title} for obj in queryset] class Meta: model=models.CourseDetail fields=['id','name','why_study','title','img','level','chapter','recommend_course']
补充ORM跨表和构建列表:
1.ORM
FK
反向查询,表名小写+_set.all()
可以用反向字段
OnetoOne字段
反向查询 表明小写就可以进行跨表
数据结构构建补充:
ret=[{'title':'123','msg':'456'},{'title':'789','msg':'000'},] new=[{'title':row['title']} for row in ret] print(new) [{'title': '123'}, {'title': '789'}]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人