0


【Django+Vue3 线上教育平台项目实战】构建高效线上教育平台之首页模块

在这里插入图片描述


文章目录


前言

   在当今数字化教育浪潮中,构建一个高效且用户友好的线上教育平台至关重要。本博客将指导您使用Django作为后端框架,结合Vue 3的强大前端能力,快速搭建平台首页的核心功能,包括导航栏、轮播图、侧边栏、标签栏及分类课程推荐。我们将探讨前后端数据交互、Vue组件化开发等关键技术,轻松构建出既美观又实用的线上教育平台。

***  最终实现效果图如下:***
在这里插入图片描述


一、导航功能实现

a.效果图:

在这里插入图片描述

b.后端代码

导航表模型类:

classNavigationModel(BaseModel):
    name = models.CharField(max_length=100)
    url = models.CharField(max_length=100)
    is_url = models.BooleanField(default=False)def__str__(self):return self.name
    classMeta:
        verbose_name ='导航表'
        verbose_name_plural ='导航表'
        db_table ='navigation'

导航表序列化器:

classNavigationSerializer(serializers.ModelSerializer):classMeta:
        model = NavigationModel
        fields =('id','name','url','is_url')# fields = '__all__'

获取所有头部导航栏信息:

classNavigationView(APIView):defget(self, request):
        nav_list = NavigationModel.objects.all()
        ser = NavigationSerializer(nav_list, many=True)return Response({"code":"200","data":ser.data})

配置url信息:

urlpatterns =[
    path('nav/header/', NavigationView.as_view()),...]

c.前端代码

components/Header.vue:

<!-- 0.导航栏 --><ulclass="nav"><liv-for="(item,index) in nav.header_nav_list ":key="index"><a:href="item.url"v-if="item.is_url">{{item.name}}</a><router-link:to="item.url"v-else>{{item.name}}</router-link></li></ul><scriptsetup>import nav from"../api/nav"// 获取顶部导航菜单
    nav.get_header_nav()</script>

src/api/nav.js:

import http from"../http";import{reactive}from"vue";const nav =reactive({header_nav_list:[],// 头部导航列表get_header_nav(){// 获取头部导航菜单
   http.get("/home/nav/header/").then(response=>{this.header_nav_list = response.data;})},})exportdefault nav;

二、轮播图功能实现

a.效果图

在这里插入图片描述

b.后端代码

轮播图模型类:

classBannerModel(BaseModel):
    image = models.CharField(max_length=255)
    link = models.CharField(max_length=255)
    is_http = models.BooleanField(default=False)def__str__(self):return self.image
    classMeta:
        verbose_name ="轮播图表"
        verbose_name_plural ="轮播图表"
        db_table ='banner'

轮播图序列化器:

classBannerSerializer(serializers.ModelSerializer):classMeta:
        model = BannerModel
        fields ='__all__'

获取轮播图数据:

classBannerView(APIView):defget(self, request):
        banners = BannerModel.objects.all()
        ser = BannerSerializer(banners, many=True)return Response({"code":"200","data":ser.data})

配置url信息:

    path('banner/', BannerView.as_view()),

c.前端代码

src/components/Banner.vue:

<!-- 焦点图、轮播图--><divclass="g-banner-content"@mouseover="state.current_menu = -1"><el-carouselheight="382px"indicator-position="bottom"@change="handleCarouselChange"><el-carousel-itemv-for="(item, key) in banner.bannerImg":key="key"><img:src="item.image"alt=""style="width: 100%;height: 100%"/></el-carousel-item></el-carousel></div>
<script setup>import banner from"../api/banner";
banner.get_banner_list();// 轮播图列表  接口数据替换// http://192.168.56.1:3000/src/assets/img/course1.jpgconst bannerImg =reactive([{image:'/src/assets/img/course1.jpg',link:'',is_http:false,}])// 当前轮播 banner背景const nowBannerImg =reactive({src: bannerImg[0].image });//轮播切换赋值consthandleCarouselChange=(index)=>{// 更新当前banner图片地址
  nowBannerImg.src = banner.bannerImg[index].image;};<script>

src/api/banner.js:

import{ reactive }from"vue";import http from"../http";const banner =reactive({bannerImg:[],// 轮播广告列表get_banner_list(){// 获取轮播广告列表return http.get("/home/banner/").then(response=>{// console.log("Bannner---response.data");// console.log(response.data);this.bannerImg = response.data.data;// console.log("bannerImg");// console.log(response.data.data);})},})exportdefault banner;

三、标签栏功能实现

a.效果图

在这里插入图片描述

b.后端代码

标签表模型类:

classDirectionModel(BaseModel):
    direction = models.CharField(max_length=255)
    desc = models.CharField(max_length=255)
    icon = models.CharField(max_length=255)def__str__(self):return self.direction
    classMeta:
        verbose_name ="方向表"
        verbose_name_plural ="标签表"
        db_table ='direction'

标签 / 方向表序列化器:

classDirectionSerializer(serializers.ModelSerializer):classMeta:
        model = DirectionModel
        fields =['id','direction','desc','icon']# fields = '__all__'

获取所有标签数据:

classDirectionView(APIView):defget(self, request):
        directions = DirectionModel.objects.all()
        ser = DirectionSerializer(directions, many=True)return Response({"code":"200","data":ser.data})

配置urls:

    path('directions/', DirectionView.as_view()),

c.前端代码

src/components/Banner.vue:

<!-- 标签表(方向表) --><divclass="system-class-show"><aclass="show-box"v-for="(item, index) in directions.directions_list":key="index"><divclass="system-class-icon":style="{ 'background-image': `url('${item.icon}')` }"></div><divclass="describe"><h4>{{ item.direction }}</h4><p>{{ item.desc }}</p></div></a><divclass="line"></div><aclass="all-btn"><divclass="mini-title">体系课</div><divclass="more-btn">more</div></a></div>
import directions from'../api/directions';

directions.get_directions_list();

src/api/directions.js:

import{ reactive }from"vue";import http from"../http";const directions =reactive({directions_list:[],// 标签列表get_directions_list(){// 获取标签列表return http.get("/home/directions/").then(response=>{// console.log("11111111111111");// console.log("directions_list---response.data");// console.log(response.data);this.directions_list = response.data.data;// console.log(response.data.data);})},})exportdefault directions;

四、侧边栏功能实现

1.整体效果图

在这里插入图片描述

2.侧边栏功能实现

a.效果图

在这里插入图片描述

b.后端代码

分类表模型类:

classCategoryModel(BaseModel):id= models.AutoField(primary_key=True)# 通常Django会自动为主键添加AutoField,这里显式写出也可以
    name = models.CharField(max_length=255, unique=True)# 假设分类名最大长度为255个字符
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='son')# 自关联字段,表示父分类
    recommend = models.BooleanField(default=False)def__str__(self):return self.name
    classMeta:
        verbose_name ='分类表'
        verbose_name_plural ='分类表'
        db_table ='category'

父级分类序列化器、子级分类序列化器:

# 子类序列化器---二级分类classSonCategorySerializer(serializers.ModelSerializer):classMeta:
        model = CategoryModel
        fields =('id','name')# fields = '__all__'# 父类序列化器--一级分类classCategorySerializer(serializers.ModelSerializer):
    son = SonCategorySerializer(many=True, read_only=True)classMeta:
        model = CategoryModel
        fields ='__all__'# fields = ('id','name','son')

获取父级与子级分类:

# 2.获取一、二级分类classCategoryView(APIView):defget(self, request):# 查询所有一级分类:parent is null# query_set
        categories = CategoryModel.objects.filter(is_delete=0,parent__id__isnull=True)#query_set

        clist =[]#侧边栏 二级分类显示几个for category in categories:# 获取一级下面所有的二级分类,操作显示二级分类数据条数
            sondata = category.son.all()[0:2]#query_set# d对二级数据进行序列化操作
            son = SonCategorySerializer(sondata, many=True)
            clist.append({"id": category.id,"name": category.name,"son": son.data})return Response({"code":"200","data":clist})

配置url:

    path('nav/cates/', CategoryView.as_view()),#侧边栏-获取一二级分类 

c.前端代码

src/components/Banner.vue:

<!-- 左侧边栏Banner---二级分类 --><divclass="menuContent"><divv-for="(item, index) in cates.cates_list":key="index"class="item":class="{ 'js-menu-item-on': state.current_menu == 0 }"@mouseover="fnMethod(item.id)"><!-- item.id 一级分类id --><spanclass="title">{{ item.name }}:</span><spanclass="sub-title"v-for="(s, index) in item.son":key="index">&nbsp;&nbsp;{{ s.name }}&nbsp;&nbsp;</span><iclass="imv2-arrow1_r"></i></div></div>
import cates from"../api/cates";

cates.get_cates_list();// 定义方法-展示侧边栏所有二级分类以及所有分类下的课程constfnMethod=(cateid)=>{
  state.current_menu =0;
  cates.get_coures_list(cateid);};

src/api/cates.js:

import http from"../http";import{ reactive }from"vue";const cates =reactive({cates_list:[],// Banner---两级分类列表get_cates_list(){// 获取两级分类return http.get("/home/nav/cates/").then(response=>{// console.log("左侧边栏获取两级分类response.data:");// console.log(response.data);this.cates_list = response.data.data;})},})exportdefault cates;

3.侧边栏展示分类及课程信息功能实现

点击分类(侧边栏触发),获取此分类下所有的二级分类(@mouseover)以及此分类下推荐的课程

a.效果图

在这里插入图片描述

b.后端代码

+课程表模型类:

classCourseModel(BaseModel):id= models.AutoField(primary_key=True)
    name = models.CharField(max_length=255, unique=True)# parent 指向 Category 分类id
    parent = models.ForeignKey(CategoryModel, on_delete=models.CASCADE, related_name='course',verbose_name="parent-父级分类")
    topid = models.IntegerField(verbose_name="topid-顶级分类")

    recommend = models.BooleanField(default=False)
    picurl = models.CharField(max_length=100)
    price = models.FloatField()
    level = models.IntegerField(verbose_name="1零基础 2中级 3高级")
    sales = models.IntegerField(default=0,verbose_name="销量")
    describe = models.TextField()def__str__(self):return self.name
    classMeta:
        verbose_name ='课程表'
        verbose_name_plural ='课程表'
        db_table ='course'

课程序列化器:

classCourseSerializer(serializers.ModelSerializer):# teacher = TeachersSerializer(many=True, read_only=True)# teacher = TeachersSerializer()classMeta:
        model = CourseModel
        fields ='__all__'

获取所有分类及其推荐课程:

classCategoryCourseView(APIView):defget(self, request):#获取一级分类id
        cateid = request.GET.get("cateid")#根据id查询分类:一级分类和二级分类
        cate = CategoryModel.objects.filter(id=cateid).first()#通过id查询推荐课程
        ser = CategorySerializer(cate)#返回结果#print(cate.id)
        courses = CourseModel.objects.filter(topid=cateid,recommend=True)#print(courses)
        cSer = CourseSerializer(courses, many=True)#print(cSer.data)return Response({"code":"200","clist":ser.data,"courses":cSer.data})

配置urls:

    path('nav/catescourses/', CategoryCourseView.as_view()),#侧边栏-传一级分类id->展示子分类及其所有课程

c.前端代码

src/components/Banner.vue:

<!-- 侧边栏触发显示:分类信息、课程信息 --><divclass="submenu"v-if="state.current_menu === 0"><!-- 1.2.1侧边栏触发显示:商品课程二级分类信息  --><divclass="inner-box"><h2class="type">{{ cates.cc_list.name }}</h2><divclass="tag clearfix"></div><divclass="lore"><spanclass="title">知识点:</span><pclass="lores clearfix"><atarget="_blank"v-for="(item, index) in cates.cc_list.son":key="index"href="">{{ item.name }}</a></p></div></div><!-- 1.2.2侧边栏触发显示:分类下的课程信息---><divclass="recomment clearfix"><ahref=""target="_blank"title=""class="recomment-item"v-for="(c,index) in cates.course_list":key="index"><divclass="img":style="{ 'background-image': `url('${c.picurl}')`, 'background-size': '100%' }"></div><divclass="details"><divclass="title-box"><pclass="title"><spanclass="text">{{c.name}}</span><spanclass="tag tixi">体系</span></p></div><divclass="bottom"><spanclass="discount-name">优惠价:</span><spanclass="price">¥{{c.price}}</span>&middot;<spanclass="difficulty"> {{c.describe}} </span>&middot;<spanclass="difficulty"v-if="c.level==1"> 0基础 </span>&middot;<spanclass="difficulty"v-if="c.level==2"> 中级 </span>&middot;<spanclass="difficulty"v-if="c.level==3"> 高级 </span>&middot;<spanclass="num"><iclass="imv2-set-sns"></i> {{c.sales}}人</span></div></div></a></div></div>

src/api/cates.js:

import http from"../http";import{ reactive }from"vue";const cates =reactive({cates_list:[],// Banner---两级分类列表cc_list:{},//Banner---触发显示:显示所有二级分类course_list:[],//Banner ---触发显示:显示分类下的课程get_cates_list(){// 获取两级分类return http.get("/home/nav/cates/").then(response=>{this.cates_list = response.data.data;})},get_coures_list(cateid){// 获取所有二级分类 及其 课程return http.get("/home/nav/catescourses/?cateid="+ cateid).then(response=>{// console.log("左侧边栏获取课程分类及课程response.data:");// console.log(response.data);this.cc_list = response.data.clist;this.course_list = response.data.courses;})},})exportdefault cates;

五、分类课程推荐(楼层设计)功能实现

首页分类课程推荐设计:
    显示推荐分类,获取不同楼层不同分类下的课程,点击不同分类时获取当前楼层分类下的推荐课程并显示

a.效果图

在这里插入图片描述

b.后端代码

为了便于理解,建立三张表:频道表、频道分类表、频道课程表,模型类如下:

# a.频道表classChannelModel(BaseModel):
    name = models.CharField(max_length=255, unique=True)
    picurl = models.CharField(max_length=100)
    sort = models.IntegerField()def__str__(self):return self.name
    classMeta:
        verbose_name ='频道表'
        verbose_name_plural ='频道表'
        db_table ='channel'# b.频道分类表 id,name,显示顺序,频道id,类别(1-添加的 2-分类的),分类idclassChannelCategoryModel(BaseModel):
    name = models.CharField(max_length=255)
    sort = models.IntegerField()
    channel = models.ForeignKey(ChannelModel, on_delete=models.CASCADE, related_name='cates')type= models.IntegerField()
    cateid = models.IntegerField()def__str__(self):return self.name

    classMeta:
        verbose_name ='频道分类表'
        verbose_name_plural ='频道分类表'
        db_table ='channel_cates'# c.频道分类课程表 id,name,图标,价格,难度,购买人数,频道分类idclassChannelCoursesModel(BaseModel):
    name = models.CharField(max_length=255,unique=True)
    picurl = models.CharField(max_length=100)
    price = models.FloatField()
    sales = models.IntegerField(default=0)
    level = models.IntegerField()
    ccates = models.ForeignKey(ChannelCategoryModel, on_delete=models.CASCADE, related_name='courses')def__str__(self):return self.name
    classMeta:
        verbose_name ='频道分类课程表'
        verbose_name_plural ='频道分类课程表'
        db_table ='channel_courses'

频道、频道分类、频道课程序列化器:

# --# c.频道分类课程序列化器classChannelCourseSerializer(serializers.ModelSerializer):classMeta:
        model = ChannelCoursesModel
        fields ='__all__'# b.频道分类序列化器-classChannelCategorySerializer(serializers.ModelSerializer):
    courses = ChannelCourseSerializer(many=True, read_only=True)classMeta:
        model = ChannelCategoryModel
        fields ='__all__'# a.频道序列化器classChannelSerializer(serializers.ModelSerializer):
    cates = ChannelCategorySerializer(many=True, read_only=True)classMeta:
        model = ChannelModel
        fields ='__all__'

获取首页推荐课程分类信息:

# 6.2 楼层-课程卡片--(无顺序版-->直接嵌套序列化器)classHomeCourseView(APIView):defget(self, request):
        channels = ChannelModel.objects.order_by('sort').all()
        ser_channels = ChannelSerializer(channels, many=True)return Response({"code":"200","data":ser_channels.data})

配置urls:

    path('homecourse/', HomeCourseView.as_view()),#首页推荐分类课程

c.前端代码

src/components/NewCourse.vue:

<template><divclass="bg000"><divclass="container-types new-course"v-for="record,index in course.data":key="index"><!-- 第一级:pic --><h3class="types-title justify-content_flex-start":style="{ 'background-image': `url('${record.picurl}')` }">{{index}}

        <!-- 第二级 eg:推荐、前端课程 --><ulclass="menu"><li:class="{'curr': state.current_menu[index]==key}"v-for="item,key in record.cates":key="key"@click="selectTab(item,key,index)"><a>{{ item.name }}</a></li></ul></h3><!-- 对应分类下的课程信息 --><divclass="list clearfix show"><aclass="item"v-for="citem,cindex in record.cates[courseList.data[index]].courses":key="cindex"><divclass="img":style="{ 'background-image': `url('${citem.picurl}')` }"></div><divclass="title ellipsis2">{{ citem.name }}</div><divclass="difficulty">{{ citem.level }} · {{ citem.person }}人报名</div><divclass="bottom clearfix"><spanclass="price l red bold">¥{{ citem.price }}</span></div></a></div></div></div></template>
<script setup>import{reactive}from"vue"// 接口取回的数据import course from"../api/home";

course.get_courses_list();// 定义每个频道TAB的下标let courseList =reactive({data:[0,0,0]})// 点击事件item-cates,key-二级index,index-一级indexconstselectTab=(item,key,index)=>{
  courseList.data[index]= key
  state.current_menu[index]= key
}const state =reactive({current_menu:[0,0,0],})</script>

src/api/home.js:

import{ reactive }from"vue";import http from"../http";const course =reactive({data:[],// 分类下课程信息get_courses_list(){// 获取分类下课程信息return http.get("/home/homecourse/").then(response=>{
      console.log("response.data.data");
      console.log(response.data.data);this.data = response.data.data;},})exportdefault course;

在这里插入图片描述

标签: django python 后端

本文转载自: https://blog.csdn.net/m0_48173416/article/details/140361883
版权归原作者 么凹猫' 所有, 如有侵权,请联系我们删除。

“【Django+Vue3 线上教育平台项目实战】构建高效线上教育平台之首页模块”的评论:

还没有评论