zoukankan      html  css  js  c++  java
  • 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/>'
    })
    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>

     这里的数据是假数据,所以应该真正的去后端创建数据表,并且编写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
    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的序列化类。


    最终效果:

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

    # 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里面对详情页进行了数据传送:

    <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



  • 相关阅读:
    图文详解QT布局管理器
    osg中放大缩小模型
    osgearth中XML文档读取报错
    中国河南省洛阳市嵩县黄庄乡红堂村大树芽组
    GIS数据下载整合
    四面体剖分相关开源软件列表
    在你的QT工程中使用ui文件
    对osgAnimation例子的注释的注释
    [debug]调试Release版本应用程序
    链表面试题总结
  • 原文地址:https://www.cnblogs.com/geogre123/p/9792781.html
Copyright © 2011-2022 走看看