Vue向后端请求课程展示

摘要:
1.Vue结构应用程序。vue主页课程微位置深度技术˂

1.Vue结构

Vue向后端请求课程展示第1张

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一样。

Vue向后端请求课程展示第2张Vue向后端请求课程展示第3张
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/>'
})
View Code

在课程中向后端发送请求并用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>

Vue向后端请求课程展示第4张

 这里的数据是假数据,所以应该真正的去后端创建数据表,并且编写API接口

1.创建models表

Vue向后端请求课程展示第5张Vue向后端请求课程展示第6张
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
View Code

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的序列化类。


最终效果:

Vue向后端请求课程展示第7张

Vue向后端请求课程展示第8张

 最后做了一点优化以及解耦的分离:

Vue向后端请求课程展示第9张Vue向后端请求课程展示第10张
# 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]
View Code

在前端Vue里面对详情页进行了数据传送:

Vue向后端请求课程展示第11张Vue向后端请求课程展示第12张
<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>
View Code



免责声明:文章转载自《Vue向后端请求课程展示》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇spring boot入门笔记 (三)基本的查询语句下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vue 借用element-ui实现头像上传 axios发送请求

<!-- 上传组件 --> <!-- 总结一下: action 写图片上传请求的路径 去路径哈 show-file-list就是当你上传时,是否会显示出上传的是哪一个图片,一般为false handleAvatarSuccess它是成功的回调 beforeAvatarUpload:上传之前做的一...

tensorflow 2.0 学习(二)线性回归问题

线性回归问题 1 # encoding: utf-8 2 3 import numpy as np 4 import matplotlib.pyplot as plt 5 6 data = [] 7 for i in range(100): 8 x = np.random.uniform(-10., 10.) #均匀分布产...

Vue--爬坑

1.路由变化页面数据不刷新问题; 出现这种情况是因为依赖路由的params参数获取写在created生命周期里面,因为相同路由二次甚至多次加载的关系 没有达到监听,退出页面再进入另一个文章页面并不会运行created组件生命周期,导致文章数据还是第一次进入的数据。 解决方法:watch监听路由是否变化 解决方法:watch监听路由是否变化 watch: {...

Indigo参考 (2) DataContract 使用 详解(转)

在阅读之前,请先阅读我写过的第一篇有关Indigo的文章. Data Contract是用来定义Indigo Service与Client端之间用来交换的数据的格式,如果我们需要传递自定义的数据,那么就需要将其定义为符合Indigo规范的Data Contract。数据里面的每一个数据项,被成为Data Member。 [DataContract] pu...

Vue 数组和对象更新,但是页面没有刷新

在使用数组的时候,数组内部数据发生改变,但是与数组绑定的页面的数据却没有发生变化。 <ul> <li v-for="(item,index) in todos" :key="index">{{item.name}}</li> </ul>    data () { return {...

pandas DataFrame.where() 检查一个或多个条件的数据帧,并相应地返回结果

    Python是进行数据分析的一种出色语言,主要是因为以数据为中心的python软件包具有奇妙的生态系统。Pandas是其中的一种,使导入和分析数据更加容易。 where()方法用于检查一个或多个条件的数据帧,并相应地返回结果。默认情况下,不满足条件的行将填充为NaN值。 Syntax:DataFrame.where(cond,other = na...