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向后端请求课程展示的更多相关文章

  1. vue中Axios请求豆瓣API数据并展示到Swipe中

    vue中Axios请求豆瓣API数据并展示到Swipe中 1.首先是安装Axios: 安装方法cnpm install axios --save 等待npm安装完毕: 2.在main.js中引入axi ...

  2. ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

    前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...

  3. Flask + vue 前后端分离的 二手书App

    一个Flask + vue 前后端分离的 二手书App 效果展示: https://blog.csdn.net/qq_42239520/article/details/88534955 所用技术清单 ...

  4. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题

    原文链接:https://segmentfault.com/a/1190000012879279 当前后端分离时,权限问题的处理也和我们传统的处理方式有一点差异.笔者前几天刚好在负责一个项目的权限管理 ...

  5. 解决Django+Vue前后端分离的跨域问题及关闭csrf验证

      前后端分离难免要接触到跨域问题,跨域的相关知识请参:跨域问题,解决之道   在Django和Vue前后端分离的时候也会遇到跨域的问题,因为刚刚接触Django还不太了解,今天花了好长的时间,查阅了 ...

  6. 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  7. 两个开源的 Spring Boot + Vue 前后端分离项目

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  8. beego-vue URL重定向(beego和vue前后端分离开发,beego承载vue前端分离页面部署)

    具体过程就不说,是搞这个的自然会动,只把关键代码贴出来. beego和vue前后端分离开发,beego承载vue前端分离页面部署 // landv.cnblogs.com //没有授权转载我的内容,再 ...

  9. Vue获取后端数据 渲染页面后跳转

    主页面 <template> <div> <ul v-for="item in courseList"> <router-link :to ...

随机推荐

  1. logstash配置

    input { #You must define a [type], otherwise you cannot get a field to cut. tcp { port => 5045 ty ...

  2. kali系统固化到固态硬盘小记(赠送给广大折腾党的笔记)

    1.首先你需要一个移动硬盘和一个移动硬盘盒子(一根数据转换线,一般买盒子商家会赠送的) SSD硬盘要事先格式化一下格式,不然识别不出来 2.准备好Kali镜像,传送门在这里https://www.ka ...

  3. 【Git 学习三】深入理解git reset 命令

    重置命令(git reset)是Git 最常用的命令之一,也是最危险最容易误用的命令.来看看git reset命令用法. --------------------------------------- ...

  4. 多个iframe中根据src获取特定iframe并执行操作

    多个iframe中根据src获取特定iframe并执行操作 前言:在项目中做一个批量编辑工单时需要在一大堆的iframe中的某一个iframe里边再用模态框的形式显示编辑区域,然后再在模态框里边加入i ...

  5. ORCFILE IN HDP 2: BETTER COMPRESSION, BETTER PERFORMANCE

    ORCFILE IN HDP 2: BETTER COMPRESSION, BETTER PERFORMANCE by Carter Shanklin   The upcoming Hive 0.12 ...

  6. node基础—模块系统

    模块的概念 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块加载系统. 在 Node.js 中,文件和模块是一一对应的(每个文件被视为一个独立的模块),换言之,一个 Node ...

  7. SQLite的sqlite3_prepare_v2

    original SQL text---<sqlite3_prepare_v2>--->sqlite3_stmt--<sqlite3_reset>-->clear  ...

  8. [2] LabelImg图片标注 与 YOLOv3 网络训练 (待补充)

    LabelImg是一个图形图像注释工具. 它是用Python编写的,并使用Qt作为其图形界面. 注释以PASCAL VOC格式保存为XML文件,这是ImageNet使用的格式.Besdies,它也支持 ...

  9. icon图标库记录

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 阿里巴巴: http://iconfont.cn/ 可以下载图标 github : x ...

  10. 兼容Android 和 ios JavaScript copy paste

    <!DOCTYPE html> <html> <head> <title>关于我们Frame</title> <meta charse ...