Django blog项目《二十二》:后台admin《视频管理功能实现》

课程视频管理功能,实现课程视频的增、删、改、查和图片上传到服务器功能功能的实现一、分析1. 业务流程1. 课程视频展示业务流程根据提供信息进行课程视频查找(参照文章管理)从后端查取数据返回到前端,进行页面填充请求方式、地址、参数请求方式:GET请求地址:/admin/course/权限:view_course请求参数:参数名类型...
摘要由CSDN通过智能技术生成

课程视频管理功能,实现课程视频的增、删、改、查和图片上传到服务器功能功能的实现

一、分析

1. 业务流程

1. 课程视频展示
  1. 业务流程

    • 根据提供信息进行课程视频查找(参照文章管理)
  • 从后端查取数据返回到前端,进行页面填充
  1. 请求方式、地址、参数

    • 请求方式:GET

    • 请求地址:/admin/course/

    • 权限:view_course

    • 请求参数:

      参数名 类型 是否必传 备注
      start_time datatime 不是必传 form表单参数
      end_time datatime 不是必传 form表单参数
      title char 不是必传 form表单参数
      teacher char 不是必传 form表单参数
      cate_id int 不是必传 form表单参数
2. 课程视频删除功能
  1. 业务流程

    • 从前端传递一个带有视频id的delete请求
    • 判断数据库中是否有该数据
    • 逻辑删除该课程视频,并返回数据到前端
  2. 请求方式、地址、参数

    • 请求方式:DELETE

    • 请求地址:/admin/course/edit/<int:course_id>/

    • 权限:delete_course

    • 请求参数:

      参数名 类型 是否必传 备注
      course_id int 必传 路径参数
3. 课程视频修改功能
  1. 业务流程

    • 判断课程视频名、课程视频简介、课程视频封面图、课程视频分类、课程视频url、课程大纲是否为空
    • 判断数据库中是否存在id=doc_id的数据
    • 进行表单校验
    • 成功后将数据保存进数据库
      • 将数据返回到前端
  2. 请求方式、地址、参数

    • 请求方式:PUT

    • 请求地址:/admin/course/edit/<int:course_id>/

    • 权限:change_course

    • 请求参数:

      参数名 类型 是否必传 备注
      course_id int 必传 路径参数
      name char 必传 请求体里
      brief char 必传 请求体里
      category int 必传 路径参数
      teacher int 必传 路径参数
      cover_url url 必传 请求体里
      video_url url 必传 请求体里
      outline text 必传 请求体里
  3. 前端功能实

    • 判断课程视频名、课程视频简介、课程视频封面图、课程视频分类、课程视频url、课程大纲是否为空

    • 发起ajax PUT请求

      • 跳转到课程视频管理页面
  4. 后端逻辑处理

    • 接收前端传来的数据并转化为字典
    • 通过form表单校验上面数据
    • 校验成功后将数据保存进数据库
  • 返回数据到前端
4. 课程视频发布功能
  1. 业务流程

    • 判断课程视频名、课程视频简介、课程视频封面图、课程视频分类、课程视频url、课程大纲是否为空
    • 进行表单校验
    • 成功后将数据保存进数据库
    • 将数据返回到前端
  2. 请求方式、地址、参数

    • 请求方式:POST

    • 请求地址:/admin/course/pub/

    • 权限:add_course

    • 请求参数:

      参数名 类型 是否必传 备注
      name char 必传 请求体里
      brief char 必传 请求体里
      category int 必传 路径参数
      teacher int 必传 路径参数
      cover_url url 必传 请求体里
      video_url url 必传 请求体里
      outline text 必传 请求体里
  3. 前端功能实

    • 判断课程视频名、课程视频简介、课程视频封面图、课程视频分类、课程视频url、课程大纲是否为空

    • 发起ajax POST请求

      • 跳转到课程视频管理页面
  4. 后端逻辑处理

    • 接收前端传来的数据并转化为字典
    • 通过form表单校验上面数据
    • 校验成功后将数据保存进数据库
    • 返回数据到前端
5. 上传视频到阿里云
  1. 业务流程

    • 构建一个百度云视频上传接口

    • 判断课程名是否为空

    • 判断课程简介是否为空

    • 调用百度VOD接口上传视频

二、课程视频展示功能实现

1. urls配置
from django.urls import path

from admin import views

app_name = "admin"

urlpatterns = [

    path("course/", views.CourseIndexView.as_view(), name="course"),
    path("course/edit/<int:course_id>/", views.CourseEditView.as_view(), name="course_edit"),
    path("course/pub/", views.CoursePubView.as_view(), name="course_pub"),

]

2. views视图逻辑处理
import json
from datetime import datetime
from urllib.parse import urlencode
from collections import OrderedDict  # 转化为字典

from django.views import View
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin

from news import models
from admin import contains
from settings import FDFS_URL
from course.models import Course, CourseCategory, Teacher
from users.models import Users
from utils.fast.fdfs import client
from admin.forms import ArticleEditForm, DocEditForm, CourseEditForm
from utils.page.per_page import get_page_data
from utils.res_code.res_code import Code, error_map
from utils.res_code.json_function import to_json_data


# 课程视频展示
class CourseIndexView(PermissionRequiredMixin, View):
    """
    course video show page
    route:/admin/course/
    permissions:view_course
    """
    permission_required = ("course.view_course",)
    raise_exception = True

    def get(self, request):
        # 1. 从数据库中获取到文档的数据
        course = Course.objects.select_related("teacher", "category").only("id", "name", "teacher__name",
                                                                           "category__name", "update_time").filter(
            is_delete=False).order_by("-update_time", "-id")

        category = CourseCategory.objects.only("name").filter(is_delete=False)

        # 2. 获取前端传来的数据:判断1个获取一个:start_time、end_time、doc_title、doc_author
        # 判断起始时间start_time
        try:
            start_time = request.GET.get("start_time", "").strip()
            start_time = datetime.strptime(start_time, "Y%m%d%")
        except Exception as e:
            # logger.info("起始时间格式错误:{}".format(e))
            start_time = ""

        # 判断结束时间end_time
        try:
            end_time = request.GET.get("end_time", "").strip()
            end_time = datetime.strptime(end_time, "Y%m%d%")
        except Exception as e:
            # logger.info("起始时间格式错误:{}".format(e))
            end_time = ""

        # 判断起始时间和结束时间输入的三种情况:1.起始时间有、结束无;2.起始时间无、结束时间有;3.起始时间大于结束时间
        # 起始时间有、结束无
        if start_time and not end_time:
            course = course.filter(update_time__lte=start_time)

        # 起始时间无、结束时间有
        if end_time and not start_time:
            course = course.filter(update_time__gte=end_time)

        # 起始时间大于结束时间
        if start_time and end_time:
            course = course.filter(update_time__range=(start_time, end_time))
            if not course:
                return to_json_data(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])

        # 3. 对文章标题进行判断/模糊查询
        name = request.GET.get("name", "").strip()
        if name:
            course = course.filter(is_delete=False, name__icontains=name)

        # 4. 对文章作者进行判断模糊查询
        teacher = request.GET.get("teacher_name", "").strip()
        if teacher:
            course = course.filter(is_delete=False, teacher__name__icontains=teacher)

        cate_id = int(request.GET.get("category", "0"))
        if cate_id:
            course = course.filter(is_delete=False, category=cate_id)

        # 5. 进行分页处理
        try:
            page_num = int(request.GET.get("page", 1))
        except Exception as e:

            logger.info("页码格式错误:{}".format(e))
            page_num = 1

        page_obj = Paginator(course, contains.PER_PAGE_NUMBER)

        try:
            course_info = page_obj.page(page_num)
        except EmptyPage:  # 页码为空
            course_info = page_obj.page(page_obj.num_pages)

        pages_data = get_page_data(page_obj, course_info)

        # 将时间转化为字符串
        start_time = start_time.strftime("%Y%m%d") if start_time else ""
        end_time = end_time.strftime("%Y%m%d") if end_time else ""
        # 6. 将数据传递给前端
        data = {
   
            'course_info': course_info,
            "categories": category,
            'paginator': page_obj,
            'start_time': start_time,
            'end_time': end_time,
            'name': name,
            'teacher': teacher,
            "cate_id": cate_id,
            'other_param': urlencode({
   
                'start_time': start_time,
                'end_time': end_time,
                'name': name,
                'teacher': teacher,
                "cate_id": cate_id,
            })
        }
        data.update(pages_data)

        return render(request, 'admin/course/course_index.html', context=data)
3. js前端逻辑处理
$(function () {
   
    let $startTime = $("input[name=start_time]");
    let $endTime = $("input[name=end_time]");
    const config = {
   

        autoclose: true,// 自动关闭

        format: 'yyyy/mm/dd',// 日期格式

        language: 'zh-CN',// 选择语言为中文

        showButtonPanel: true,// 优化样式

        todayHighlight: true, // 高亮今天

        calendarWeeks: true,// 是否在周行的左侧显示周数

        clearBtn: true,// 清除

        startDate: new Date(1900, 10, 1),// 0 ~11  网站上线的时候

        endDate: new Date(), // 今天
    };
    $startTime.datepicker(config);
    $endTime.datepicker(config);


    //文档删除
    let $delBtn = $(".btn-del");
    $delBtn.click(function () {
   
        let _this = this;
        let sCourseId = $(this).data("course-id");
        fAlert.alertConfirm({
   
            title: "确定删除该课程吗?",
            type: "error",
            confirmButtonText: "确认删除",
            cancelButtonText: "取消",
            confirmCallback: function confirmCallback() {
   
                $.ajax({
   
                    url: "/admin/course/edit/" + sCourseId + '/',
                    type: "DELETE",
                    dataType: "json",
                })
                    .done(function (res) {
   
                        if (res.errno === "200") {
   
                            message.showSuccess("成功删除课程!");
                            $(_this).parents("tr").remove()
                        } else {
   
                            swal.showInputError("删除失败:" + res.errmsg);
                        }
                    })
                    .fail(function () {
   
                        alert("服务器超时,请重试!")
                    })


            }
        })


    });


    // 获取cookie
    function getCookie(name) {
   
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
   
            let cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
   
                let cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
   
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    function csrfSafeMethod(method) {
   
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    // 添加token到request中
    $.ajaxSetup({
   
        beforeSend: function (xhr, settings) {
   
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
   
                xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
            }
        }
    });
});
4. html页面填充
{% extends 'admin/base/base.html' %}
{% load staticfiles %}

{% block title %}
    课程管理页
{% endblock %}

{% block css %}
    <link rel="stylesheet" href="{% static 'css/admin/news/bootstrap-datepicker.min.css' %}">
{% endblock %}

{% block content_header %}
    课程管理
{% endblock %}

{% block content_header_brief %}
    课程的增删改查
{% endblock %}


{% block content %}
    <style>
        .ml20 {
    
            margin-left: 20px;
        }

        .mt20 {
    
            margin-top: 20px;
        }
    </style
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值