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 ...
随机推荐
- IIS 部署问题 404
在部署IIS环境中,偶尔会遇到 404 错误,就算以前遇到过,也因为时间久了导致大概知道是什么错了,具体解决方案觉忘了,所以留下一个记录,留给自己,也是给大家一点提醒.(注:错误信息也懒得截图了,希望 ...
- LeetCode算法题-Excel Sheet Column Title(Java实现)
这是悦乐书的第180次更新,第182篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第39题(顺位题号是168).给定正整数,返回Excel工作表中显示的相应列标题.例如: ...
- February 27th, 2018 Week 9th Tuesday
Great minds think alike. 英雄所见略同. If great minds really did think alike, then we would live in an unr ...
- 我的第一个SolidWorks图
1. 学习到的知识点 2. 完成的工程图 3. 感受 学习是一种快乐,学到新的知识要学会分享,只要坚持,就有那么一点点的成就. 4. 参考 SolidWorks帮助文档
- 06.Python网络爬虫之requests模块(2)
今日内容 session处理cookie proxies参数设置请求代理ip 基于线程池的数据爬取 知识点回顾 xpath的解析流程 bs4的解析流程 常用xpath表达式 常用bs4解析方法 引入 ...
- HTML做的网页 如何使当前页面跳转到另一页面锚点处
当前页面a.html另一页面b.html当前页面: <a href="b.html#aaa">跳转到b页面aaa处</a>另一页面:<a name=& ...
- Harbor是什么
第一次听到这个名字应该是2016年初的时候,那是在容器技术已经兴起的,各个容器管理平台正处于群雄逐鹿的时候,mesos.kubernetes.swarm等被国内外各个厂商用来作为容器的管理系统.这个时 ...
- 如何在excel单元格中插入图片批注
在excel单元格中插入图片批注的方法: 1.选定要插入图片的单元格,然后右键选择插入批注. 2.然后会插入一个批注框,为了不影响图片效果,可以将批注文字都删除.然后鼠标移动到批注框边角再右键. 3. ...
- linux命令中的“<”和“|”是什么意思?
”<” 表示的是输入重定向的意思,就是把<后面跟的文件取代键盘作为新的输入设备.”| ”则表示一个管道的意思,可以理解为东西从管道的一边流向另外一边. cat file.json | ...
- Linux下su 与 su - 区别
Linux中切换用户的命令是su或su -.su命令和su -命令最大的本质区别就是:前者只是切换了root身份,但Shell环境仍然是普通用户的Shell:而后者连用户和Shell环境一起切换成ro ...