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 ...
随机推荐
- JAVA 容易忽略的东西
Java中的取余会出现负数.用Math.floorMod()方法可以掰正,但是也仅限被除数是负数的情况,如果除数是负数,这个没用. 和C不一样,Java中的字符串是不可变字符串,不能修改Java字符串 ...
- Announcing the Updated NGINX and NGINX Plus Plug‑In for New Relic (Version 2)
In March, 2013 we released the first version of the “nginx web server” plug‑in for New Relic monitor ...
- Mysql 关键字的优先级 分组 多表联查
查看模式 select @@global.sql_mode; 关键字的优先级 from 来自 where 条件 group by 分组 having 筛选 select 查询 distinct 去重 ...
- Python requests上传文件demo
#!/usr/bin/env python # -*- coding: utf-8 -*- import requests headers = {'uuid': '5cb572b7-c0a7-4d90 ...
- wxWidgets 在 Linux 下开发环境配置
本文基于 CodeBlocks (16.0.1) 和 wxWidgets (3.0.2) 搭建 Linux 下 GUI 开发环境. 1. 安装 CodeBlocks Ubuntu 默认的源当前 Cod ...
- robotframework日志中文乱码,编译提示‘utf-8’ codecxxxx。
1.需要设置robotframework的语系 2.设置完后,需要重启robotframework才生效.它比较特别,什么改变都要重启才生效
- js截取url参数
举例说明,比如http://localhost:2019/blog/getCommentListInfo?postId=1如何获取postId=1这个参数值呢?很简单通过下面代码即可获取,如: win ...
- oracle(环境搭建一)
图形化安装Oracle11gR2 环境: verify: CentOS release 6.5 (Final) release:CentOS release 6.7 (Final) 1.登录到root ...
- XSS高级利用
XSS会话劫持 (1)Cookie简介 Cookie是能够让网站服务器把少量文本数据存储到客户端的硬盘.内存,或者是从客户端的硬盘.内存读取数据的一种技术. Cookie是一段随HTTP请求.响应一起 ...
- 初学Python——面向对象编程
一.面向对象 or 面向过程? 编程范式: 编程是 程序 员 用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所 ...