Vue向后端请求课程展示
1.Vue结构

App.vue
<template>
<div id="app">
<router-link to="/index">首页</router-link>
<router-link to="/course">课程</router-link>
<router-link to="/micro">微职位</router-link>
<router-link to="/news">深科技</router-link>
<router-view/>
</div>
</template> <script>
export default {
name: 'App'
}
</script> <style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
color: #2c3e50;
}
</style>
这里进行利路由设置,那么需要在index中进行挂载
import Vue from 'vue'
import Router from 'vue-router'
// 导入模块
import Index from '../components/Index'
import Course from '../components/Course'
import Micro from '../components/Micro'
import News from '../components/News'
import Detail from '../components/Detail' Vue.use(Router); export default new Router({
routes: [
{
path: '/index',
name: 'index',
component: Index
},
{
path: '/course',
name: 'course',
component: Course
},
{
path: '/detail/:id',
name: 'detail',
component: Detail
}, {
path: '/micro',
name: 'micro',
component: Micro
},{
path: '/news',
name: 'news',
component: News
} ],
mode:'history' //取出url里面的#号
})
在main.js中导入axios,和ajax一样。
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios' //在vue的全局变量中设置了$axios=axios
//以后每个组件使用时:this.$axios
Vue.prototype.$axios=axios; Vue.config.productionTip = false; /* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
在课程中向后端发送请求并用v-for进行展示
<template>
<div>
<h1>课程列表</h1>
<ul v-for="row in courseList">
<li><router-link :to="{name:'detail',params:{id:row.id}}">{{row.title}}</router-link></li>
//这里利用:to来传入一个课程的ID,这样可以知道点击哪个课程的详细页。
</ul>
</div>
</template> <script>
export default {
name: "course",
data(){
return {
msg:"课程",
courseList:[ ]
}
},
mounted:function () {
//vue页面刚加载时执行
this.initCourse()
},
methods:{ initCourse:function () {
//去通过ajax向接口发送请求并获取课程列表数据
//axios/jquery
//第一步在main.js中配置
//第二部使用axios发送请求
var that = this;
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/course/',
method:'GET',
}).then(function(ret){
//ajax请求发送成功后,获取响应内容
console.log(ret.data)
if (ret.data.code ===1000){
that.courseList=ret.data.data
} }).catch(function(ret){
//上面发生异常执行这个 })
}
}
}
</script>
<style scoped>
</style>
这边设置好后,在Detail.vue中
<template>
<h1>课程详细页面</h1>
</template> <script>
export default {
name: "detail",
data(){
return { }
},
mounted(){
console.log(this); #Vue对象
console.log(this.$route.params.id) #通过这个可以拿到这个ID,
}
}
</script> <style scoped> </style>

这里的数据是假数据,所以应该真正的去后端创建数据表,并且编写API接口
1.创建models表
from django.db import models # Create your models here.
class Course(models.Model):
'''
课程表
'''
title=models.CharField(max_length=32,verbose_name="课程名称")
course_img = models.CharField(max_length=64,verbose_name="课程图片")
level_choices=(
(1,'初级'),
(2,'中级'),
(3,'高级'),
)
level=models.IntegerField(verbose_name="课程难易",choices=level_choices,default=1)
def __str__(self):
return self.title class CourseDetail(models.Model):
'''
课程详细
'''
course = models.OneToOneField(to="Course", on_delete=models.CASCADE)
slogon=models.CharField(max_length=255,verbose_name="口号")
why=models.CharField(max_length=255,verbose_name="为什么要学")
recommend_courses=models.ManyToManyField(to="Course",verbose_name="推荐课程",related_name='rc')
def __str__(self):
return "课程详细"+self.course.title class Chapter(models.Model):
'''
章节表
'''
num=models.IntegerField(verbose_name="第几章")
name=models.CharField(max_length=32,verbose_name="章节名称")
coursedetail=models.ForeignKey("Course",on_delete=models.CASCADE,verbose_name="所属课程") def __str__(self):
return self.name
2.做一个序列化,并返回数据
from rest_framework.views import APIView
from rest_framework.response import Response
from api import models
from rest_framework import serializers class CourseSerializer(serializers.ModelSerializer):
class Meta:
model=models.Course
fields="__all__" from rest_framework.viewsets import GenericViewSet,ViewSetMixin
class CourseView(ViewSetMixin,APIView):
def list(self,request,*args,**kwargs):
'''
课程列表接口
:param request:
:param args:
:param kwargs:
:return:
'''
ret = {'code': 1000, "data": None}
try:
query=models.Course.objects.all()
ser = CourseSerializer(instance=query,many=True)
ret["data"]=ser.data
except Exception as e:
ret["code"]=1001
ret["error"]="获取课程失败"
return Response(ret) def retrieve(self,request,*args,**kwargs):
'''
课程详细的接口
:param request:
:param args:
:param kwargs:
:return:
'''
ret = {'code': 1000, "data": None}
try:
pk=kwargs.get('pk')
obj = models.Course.objects.filter(id=pk).first()
ser = CourseSerializer(instance=obj,many=False)
ret["data"] = ser.data
except Exception as e:
ret["code"]=1001
ret["error"]="获取课程失败"
return Response(ret)
3.因为后面的url使用了get不同需求的状态,所以是重写了as_view(),所以类中继承的是
ViewSetMixin,zhe这样的话,就可以对都是get请求使用同一个类,做出不同的响应,有PK的使用retrieve方法,没有的使用list方法。
urlpatterns = [
# url(r'^course/$', course.CourseView.as_view()),
# url(r'^course/(?P<pk>\d+)/$', course.CourseView.as_view()), #这种方案必须继承ViewSetMixin,它重写了as_view,可以往里添加参数
url(r'^course/$', course.CourseView.as_view({"get":"list"})),
url(r'^course/(?P<pk>\d+)/$', course.CourseView.as_view({"get":"retrieve"})), ]
最后是API接口
1.查询所有课程:
http://127.0.0.1:8000/api/v1/course/
2.查询单个课程:
http://127.0.0.1:8000/api/v1/course/1/
但是因为有了新的需求,所以需要重新的来进行更多的定制。
from rest_framework.views import APIView
from rest_framework.response import Response
from api import models
from rest_framework import serializers class CourseSerializer(serializers.ModelSerializer):
class Meta:
model=models.Course
fields="__all__" class CourseDetailSerializer(serializers.ModelSerializer):
#o2o fk,choice
title=serializers.CharField(source='course.title') #只能这里通过跨表拿到以后,在下面展示
img=serializers.CharField(source='course.course_img')
level=serializers.CharField(source='course.get_level_display') #通过get_level_display方法拿到choice对应的值,如果是方法需要加(),这里反射所以不加
#m2m
recommends = serializers.SerializerMethodField() #这个因为是多对多字段,所以需要通过一个方法来拿到 class Meta:
model=models.CourseDetail
fields=['course','title','recommends','level','img','slogon','why'] #想要展示的字段
depth:1 #展示深度,这个就是说这个表如果有跟别的表跨表就会把那个表拿过来也序列化,深度越大,越往后关联的越多。 def get_recommends(self,obj): #这里通过拿到这个queryset
#获取推荐的所有课程
query=obj.recommend_courses.all() return [{'id':row.id,'title':row.title} for row in query] #通过列表解析式将这个进行拆分成如下格式。 from rest_framework.viewsets import GenericViewSet,ViewSetMixin
class CourseView(ViewSetMixin,APIView):
def list(self,request,*args,**kwargs):
'''
课程列表接口
:param request:
:param args:
:param kwargs:
:return:
'''
ret = {'code': 1000, "data": None}
try:
query=models.Course.objects.all()
ser = CourseSerializer(instance=query,many=True)
ret["data"]=ser.data
except Exception as e:
ret["code"]=1001
ret["error"]="获取课程失败"
return Response(ret) def retrieve(self,request,*args,**kwargs):
'''
课程详细的接口
:param request:
:param args:
:param kwargs:
:return:
'''
ret = {'code': 1000, "data": None}
try:
pk=kwargs.get('pk')
obj = models.CourseDetail.objects.filter(course_id=pk).first() #这里需要做的是这里会CourseDetail里面通过course_id跨表到course表
ser = CourseDetailSerializer(instance=obj,many=False) #这里使用了新的序列化类。
ret["data"] = ser.data
except Exception as e:
ret["code"]=1001
ret["error"]="获取课程失败"
return Response(ret)
这里获取具体每一个课程想要获得更多的信息,而不是局限于那个课程表,所以建立了一个
CourseDetailSerializer的序列化类。 最终效果:


最后做了一点优化以及解耦的分离:
# Author:Jesi
# Time : 2018/10/16 14:21
from rest_framework import serializers
from api import models class CourseSerializer(serializers.ModelSerializer):
'''
课程序列化
'''
level=serializers.CharField(source='get_level_display')
class Meta:
model=models.Course
fields='__all__' class CourseDetailSerializer(serializers.ModelSerializer):
'''
课程详细序列化
''' #o2o fk,choice
title=serializers.CharField(source='course.title')
img=serializers.CharField(source='course.course_img')
level=serializers.CharField(source='course.get_level_display') #m2m
recommends = serializers.SerializerMethodField()
chapter = serializers.SerializerMethodField() class Meta:
model=models.CourseDetail
fields=['course','title','recommends','level','chapter','img','slogon','why']
depth:1 def get_recommends(self,obj):
#获取推荐的所有课程
query=obj.recommend_courses.all()
return [{'id':row.id,'title':row.title} for row in query] def get_chapter(self,obj):
#获取推荐的章节
query=obj.course.chapter_set.all()
print(query)
return [{'id':row.num,'name':row.name} for row in query]
在前端Vue里面对详情页进行了数据传送:
<template>
<div>
<h1>课程详细页面</h1>
<p>课程标题:{{detail.title}}</p>
<p>图片:{{detail.img}}</p>
<p>课程难度:{{detail.level}}</p>
<p>课程口号:{{detail.slogon}}</p> <p>为什么要学?{{detail.why}}</p>
<div>
章节:
<ul v-for="item in detail.charter">
<li>{{item.name}}</li>
</ul>
</div> <div>
推荐课程:
<ul v-for="item in detail.recommends">
<li>{{item.title}}</li>
</ul>
</div> </div> </template> <script>
export default {
name: "detail",
data(){
return {
detail:{
charter:[],
course:null,
level:null,
img:null,
title:null,
slogon:null,
why:null,
recommends:[]
} }
},
mounted(){
this.initDetail()
},
methods:{
initDetail(){
var nid=this.$route.params.id;
var that = this;
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/course/'+nid+'/',
method:"GET", }).then(function (arg) {
if (arg.data.code ===1000){
console.log(arg.data);
that.detail=arg.data.data
}else{
alert(arg.data.error)
} })
}
}
}
</script> <style scoped> </style>
Vue向后端请求课程展示的更多相关文章
- vue中Axios请求豆瓣API数据并展示到Swipe中
vue中Axios请求豆瓣API数据并展示到Swipe中 1.首先是安装Axios: 安装方法cnpm install axios --save 等待npm安装完毕: 2.在main.js中引入axi ...
- ASP.NET WebApi+Vue前后端分离之允许启用跨域请求
前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...
- Flask + vue 前后端分离的 二手书App
一个Flask + vue 前后端分离的 二手书App 效果展示: https://blog.csdn.net/qq_42239520/article/details/88534955 所用技术清单 ...
- SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题
原文链接:https://segmentfault.com/a/1190000012879279 当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理 ...
- 解决Django+Vue前后端分离的跨域问题及关闭csrf验证
前后端分离难免要接触到跨域问题,跨域的相关知识请参:跨域问题,解决之道 在Django和Vue前后端分离的时候也会遇到跨域的问题,因为刚刚接触Django还不太了解,今天花了好长的时间,查阅了 ...
- 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了
折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...
- 两个开源的 Spring Boot + Vue 前后端分离项目
折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...
- beego-vue URL重定向(beego和vue前后端分离开发,beego承载vue前端分离页面部署)
具体过程就不说,是搞这个的自然会动,只把关键代码贴出来. beego和vue前后端分离开发,beego承载vue前端分离页面部署 // landv.cnblogs.com //没有授权转载我的内容,再 ...
- Vue获取后端数据 渲染页面后跳转
主页面 <template> <div> <ul v-for="item in courseList"> <router-link :to ...
随机推荐
- python——函数之生成器
1 生成器函数的含义 生成器是一个返回可以迭代对象的函数,它是一个特殊的迭代器,但迭代器的抽象层级更高且比较复杂需要实现很多方法.相较迭代器而言,生成器简单使用. 2 生成器的创建方式 2.1 ...
- [福大软工] Z班 第13次成绩排行榜
注:本次成绩排行榜是针对华为软件云评测博客 作业要求 http://www.cnblogs.com/easteast/p/7772637.html 评分细则 (1)寻找软件的bug,功能的评测与黑箱测 ...
- Go学习笔记06-内建容器
Go学习笔记06-内建容器 Go语言 数组 *切片(Slice) #F44336 Slice的操作 Map map示例 字符处理 数组 定义数组: //这样定义数组编译器自动初始化每个元素为0 va ...
- python 守护进程、同步锁、信号量、事件、进程通信Queue
一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...
- 【ZJOI2012】灾难
[ZJOI2012]灾难 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学 ...
- 设计模式のBuilderPattern(创建者模式)----创建模式
一.产生背景 要组装一台电脑,它的组装过程基本是不变的,都可以由主板.CPU.内存等按照某个稳定方式组合而成.然而主板.CPU.内存等零件本身都是可能多变的.将内存等这种易变的零件与电脑的其他部件分离 ...
- [转]Jquery 点击图片在弹出层显示大图
这个还行不需要别的包! https://www.cnblogs.com/antis/p/7053991.html
- vue.js 官网及组件网站记录
官网 https://cn.vuejs.org/v2/guide/ 饿了么组件: http://element-cn.eleme.io/#/zh-CN/component/tree 异步请求框架插件 ...
- Python+Pycharm—学习—pip
1.pip是干什么的? 2.pip怎么安装? 3.pip怎么用?
- 深入理解Proxy 及 使用Proxy实现vue数据双向绑定
阅读目录 1.什么是Proxy?它的作用是? 2.get(target, propKey, receiver) 3.set(target, propKey, value, receiver) 4.ha ...