-
2021-11-08 10:23:24
演示界面内容如下
因为不精通前端,所以前端直接上代码:
1.新建一个目录,结构如下:
1.1 index.html文件内容如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>学生信息管理系统</title> <!-- 引入外部的样式文件 --> <link rel="stylesheet" href="./css/index.css" /> <!-- 引入Element UI样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" /> <!-- 使用CDN引入Vue模块--> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script> <!-- 引入Element组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <!-- 引入Axios组件库 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <el-container> <el-header style="height: 80px;">学生信息管理系统</el-header> <el-container> <!-- 侧边栏 --> <el-aside width="200px"> <el-menu default-active="2" class="el-menu-vertical-demo"> <el-menu-item index="1"> <i class="el-icon-menu"></i> <span slot="title">班级管理</span> </el-menu-item> <el-menu-item index="2"> <i class="el-icon-user"></i> <span slot="title">学生信息</span> </el-menu-item> <el-menu-item index="3"> <i class="el-icon-s-custom"></i> <span slot="title">讲师信息</span> </el-menu-item> <el-menu-item index="4"> <i class="el-icon-document"></i> <span slot="title">课程管理</span> </el-menu-item> </el-menu> </el-aside> <el-container> <!-- 主窗体 --> <el-main> <!-- 面包屑导航 --> <el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item>首页</el-breadcrumb-item> <el-breadcrumb-item>学生管理</el-breadcrumb-item> </el-breadcrumb> <!-- 表单 --> <el-form :inline="true" style="margin-top:30px;"> <el-row> <el-col :span="12"> <el-form-item label="请输入查询条件:"> <el-input v-model="inputStr" placeholder="输入查询条件" style="width: 420px;"> </el-input> </el-form-item> </el-col> <el-col :span="8" style="text-align: right;padding-right:10px;"> <el-button-group> <el-button type="primary" icon="el-icon-search" @click="queryStudents()">查询 </el-button> <el-button type="primary" icon="el-icon-tickets" @click="getAllStudents()">全部 </el-button> <el-button type="primary" icon="el-icon-circle-plus-outline" @click="addStudent()">添加</el-button> </el-button-group> </el-col> <el-col :span="2"> <el-upload :show-file-list="false" :http-request="uploadExcelPost"> <el-button type="primary">导入Excel</el-button> </el-upload> </el-col> <el-col :span="2"> <el-button type="primary" @click="exportToExcel()">导出Excel</el-button> </el-col> </el-row> </el-form> <!-- 表格 --> <el-table :data="pageStudents" border style="width: 100%" size="mini" @selection-change="handleSelectionChange"> <el-table-column type="selection"> </el-table-column> <el-table-column type="index" label="序号" align="center" width="60"> </el-table-column> <el-table-column prop="sno" label="学号" width="80"> </el-table-column> <el-table-column prop="name" label="姓名" width="80"> </el-table-column> <el-table-column prop="gender" label="性别" width="60"> </el-table-column> <el-table-column prop="birthday" label="出生日期" align="center" width="100"> </el-table-column> <el-table-column prop="mobile" label="电话" align="center" width="120"> </el-table-column> <el-table-column prop="email" label="邮箱" align="center" width="220"> </el-table-column> <el-table-column prop="address" label="地址" align="center"> </el-table-column> <el-table-column label="操作" width="180" align="center"> <template slot-scope="scope"> <el-button type="success" icon="el-icon-more" size="mini" circle @click="viewStudent(scope.row)"></el-button> <el-button type="primary" icon="el-icon-edit" size="mini" circle @click="updateStudent(scope.row)"></el-button> <el-button type="danger" icon="el-icon-delete" size="mini" circle @click="deleteStudent(scope.row)"></el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <el-row style="margin-top: 20px;"> <el-col :span="8" style="text-align: left"> <el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteStudents()"> 批量删除</el-button> </el-col> <el-col :span="16" style="text-align: right"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentpage" :page-sizes="[5, 10, 50, 100]" :page-size="pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </el-col> </el-row> <!-- 弹出框的学生明细表单 --> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%" @close="closeDialogForm('studentForm')"> <el-form :model="studentForm" :rules="rules" ref="studentForm" :inline="true" style="margin-left: 20px;" label-width="110px" label-position="right" size="mini"> <el-upload class="avatar-uploader" :show-file-list="false" :http-request="uploadPicturePost" :disabled="isView" style="text-align: center;margin:20px;" > <img v-if="studentForm.image" :src="studentForm.imageUrl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> <el-form-item label="学号:" prop="sno"> <el-input v-model="studentForm.sno" :disabled="isEdit||isView" suffix-icon="el-icon-edit"></el-input> </el-form-item> <el-form-item label="姓名:" prop="name"> <el-input v-model="studentForm.name" :disabled="isView" suffix-icon="el-icon-edit"> </el-input> </el-form-item> <el-form-item label="性别:" prop="gender"> <el-select v-model="studentForm.gender" :disabled="isView" placeholder="请选择性别"> <el-option value="男"></el-option> <el-option value="女"></el-option> </el-select> </el-form-item> <el-form-item label="出生日期:" prop="birthday"> <el-date-picker v-model="studentForm.birthday" value-format="yyyy-MM-dd" :disabled="isView" type="date" placeholder="选择日期" style="width:93% "> </el-date-picker> </el-form-item> <el-form-item label="手机号码:" prop="mobile"> <el-input v-model="studentForm.mobile" :disabled="isView" suffix-icon="el-icon-edit"></el-input> </el-form-item> <el-form-item label="邮箱地址:" prop="email"> <el-input v-model="studentForm.email" :disabled="isView" suffix-icon="el-icon-edit"> </el-input> </el-form-item> <el-form-item label="家庭住址:" prop="address"> <el-input v-model="studentForm.address" :disabled="isView" suffix-icon="el-icon-edit" style="width:262%"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button type="primary" size="mini" v-show="!isView" @click="submitStudentForm('studentForm')">确 定</el-button> <el-button type="info" size="mini" @click="closeDialogForm('studentForm')">取 消 </el-button> </span> </el-dialog> </el-main> <el-footer style="height: 30px;">学生信息管理系统 版权所有:Steven Wang | 2020-10-10</el-footer> </el-container> </el-container> </el-container> </div> </body> </html> <!-- 引入Vue代码 --> <script src="js/index.js"></script>
1.2 index.js文件
const app = new Vue({ el: '#app', data() { //校验学号是否存在! const rulesSNo = (rule, value, callback) => { if (this.isEdit) { callback(); } //使用Axios进行校验 axios.post( this.baseURL + 'sno/check/', { sno: value, } ) .then((res) => { //请求成功 if (res.data.code === 1) { if (res.data.exists) { callback(new Error("学号已存在!")); } else { callback(); } } else { //请求失败 callback(new Error("校验学号后端出现异常!")) } }) .catch((err) => { //如果请求失败在控制台打印 console.log(err); }); } return { students: [], //所有的学生信息 pageStudents: [], //分页后当前页的学生 baseURL: "http://192.168.182.128:8000/", inputStr: '', //输入的查询条件 selectStudents: [], //选择复选框是把选择记录存在这个几个 //====分页相关的变量==== total: 0, //数据的总行数 currentpage: 1, //当前的所在的页 pagesize: 10, //每页显示多少行数据 //====弹出框表单==== dialogVisible: false, //控制弹出框表单是否展示 dialogTitle: "", //弹出框的标题 isView: false, //标识是否是查看 isEdit: false, //标识是否是修改 studentForm: { //弹出框表单对相应绑定数据 sno: '', name: '', gender: '', birthday: '', mobile: '', email: '', address: '', image: '', imageUrl: '', }, rules: { sno: [ { required: true, message: '学号不能为空', trigger: 'blur' }, { pattern: /^[9][5]\d{3}$/, message: '学号必须是95开头的五位数', trigger: 'blur' }, { validator: rulesSNo, trigger: 'blur' }, //校验学号是否存在! ], name: [ { required: true, message: '姓名不能为空', trigger: 'blur' }, { pattern: /^[\u4e00-\u9fa5]{2,5}$/, message: '姓名必须是2-5个汉字', trigger: 'blur' }, ], gender: [ { required: true, message: '性别不能为空', trigger: 'change' }, ], birthday: [ { required: true, message: '出生日期不能为空', trigger: 'change' }, ], mobile: [ { required: true, message: '手机号码不能为空', triggler: 'blur' }, { pattern: /^[1][35789]\d{9}$/, message: '手机号码必须要符合规范', trigger: 'blur' }, ], email: [ { required: true, message: '邮箱地址不能为空', trigger: 'blur' }, { pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/, message: '邮箱地址必须要符合规范', trigger: 'blur' }, ], address: [ { required: true, message: '家庭住址不能为空', trigger: 'blur' }, ] } } }, mounted() { //自动加载数据 this.getStudents(); }, methods: { //获取所有学生信息 getStudents: function () { //记录this的地址 let that = this //使用Axios实现Ajax请求 axios .get(that.baseURL + "students/") .then(function (res) { //请求成功后执行的函数 if (res.data.code === 1) { //把数据给students that.students = res.data.data; //获取返回记录的总行数 that.total = res.data.data.length; //获取当前页的数据 that.getPageStudents(); //提示: that.$message({ message: '数据加载成功!', type: 'success' }); } else { //失败的提示! that.$message.error(res.data.msg); } }) .catch(function (err) { //请求失败后执行的函数 console.log(err); }); }, getAllStudents() { //清空输入的inputStr this.inputStr = ""; //获取所有的数据 this.getStudents(); }, //获取当前页的学生数据 getPageStudents() { //清空pageStudents中的数据 this.pageStudents = []; //获得当前页的数据 for (let i = (this.currentpage - 1) * this.pagesize; i < this.total; i++) { //遍历数据添加到pageStudent中 this.pageStudents.push(this.students[i]); //判断是否达到一页的要求 if (this.pageStudents.length === this.pagesize) break; } }, //实现学生信息查询 queryStudents() { //使用Ajax请求--POST-->传递InputStr let that = this //开始Ajax请求 axios .post( that.baseURL + "students/query/", { inputstr: that.inputStr, } ) .then(function (res) { if (res.data.code === 1) { //把数据给students that.students = res.data.data; //获取返回记录的总行数 that.total = res.data.data.length; //获取当前页的数据 that.getPageStudents(); //提示: that.$message({ message: '查询数据加载成功!', type: 'success' }); } else { //失败的提示! that.$message.error(res.data.msg); } }) .catch(function (err) { console.log(err); that.$message.error("获取后端查询结果出现异常!"); }); }, //添加学生时打开表单 addStudent() { //修改标题 this.dialogTitle = "添加学生明细"; //弹出表单 this.dialogVisible = true; }, //根据Id获取image getImageBySno(sno) { //遍历 for (oneStudent of this.students) { //判断 if (oneStudent.sno == sno) { return oneStudent.image; } } }, //查看学生的明细 viewStudent(row) { //修改标题 this.dialogTitle = "查看学生明细"; //修改isView变量 this.isView = true; //弹出表单 this.dialogVisible = true; //深拷贝方法: this.studentForm = JSON.parse(JSON.stringify(row)) //获取照片 this.studentForm.image = this.getImageBySno(row.sno); //获取照片URL this.studentForm.imageUrl = this.baseURL + 'media/' + this.studentForm.image; }, //修改学生的明细 updateStudent(row) { //修改标题 this.dialogTitle = "修改学生明细"; //修改isEdit变量 this.isEdit = true; //弹出表单 this.dialogVisible = true; //深拷贝方法: this.studentForm = JSON.parse(JSON.stringify(row)) //获取照片 this.studentForm.image = this.getImageBySno(row.sno); //获取照片URL this.studentForm.imageUrl = this.baseURL + 'media/' + this.studentForm.image; }, //提交学生的表单(添加、修改) submitStudentForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { //校验成功后,执行添加或者修改? if (this.isEdit) { //修改 this.submitUpdateStudent(); } else { //添加 this.submitAddStudent(); } } else { console.log('error submit!!'); return false; } }); }, //添加到数据库的函数 submitAddStudent() { //定义that let that = this; //执行Axios请求 axios .post(that.baseURL + 'student/add/', that.studentForm) .then(res => { //执行成功 if (res.data.code === 1) { //获取所有学生的信息 that.students = res.data.data; //获取记录条数 that.total = res.data.data.length; //获取分页信息 that.getPageStudents(); //提示: that.$message({ message: '数据添加成功!', type: 'success' }); //关闭窗体 this.closeDialogForm('studentForm'); } else { //失败的提示! that.$message.error(res.data.msg); } }) .catch(err => { //执行失败 console.log(err); that.$message.error("获取后端查询结果出现异常!"); }) }, //修改更新到数据库 submitUpdateStudent() { //定义that let that = this; //执行Axios请求 axios .post(that.baseURL + 'student/update/', that.studentForm) .then(res => { //执行成功 if (res.data.code === 1) { //获取所有学生的信息 that.students = res.data.data; //获取记录条数 that.total = res.data.data.length; //获取分页信息 that.getPageStudents(); //提示: that.$message({ message: '数据修改成功!', type: 'success' }); //关闭窗体 this.closeDialogForm('studentForm'); } else { //失败的提示! that.$message.error(res.data.msg); } }) .catch(err => { //执行失败 console.log(err); that.$message.error("修改时获取后端查询结果出现异常!"); }) }, //删除一条学生记录 deleteStudent(row) { //等待确认 this.$confirm('是否确认删除学生信息【学号:' + row.sno + '\t姓名:' + row.name + '】信息?', '提示', { confirmButtonText: '确定删除', cancelButtonText: '取消', type: 'warning' }).then(() => { //确认删除响应事件 let that = this //调用后端接口 axios.post(that.baseURL + 'student/delete/', { sno: row.sno }) .then(res => { if (res.data.code === 1) { //获取所有学生信息 that.students = res.data.data; //获取记录数 that.total = res.data.data.length; //分页 that.getPageStudents(); //提示 that.$message({ message: '数据删除成功!', type: 'success' }); } else { that.$message.error(res.data.msg); } }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); }, deleteStudents() { //等待确认 this.$confirm("是否确认批量删除" + this.selectStudents.length + "个学生信息吗?", '提示', { confirmButtonText: '确定删除', cancelButtonText: '取消', type: 'warning' }).then(() => { //确认删除响应事件 let that = this //调用后端接口 axios.post(that.baseURL + 'students/delete/', { student: that.selectStudents }) .then(res => { if (res.data.code === 1) { //获取所有学生信息 that.students = res.data.data; //获取记录数 that.total = res.data.data.length; //分页 that.getPageStudents(); //提示 that.$message({ message: '数据批量删除成功!', type: 'success' }); } else { that.$message.error(res.data.msg); } }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); }, //关闭弹出框的表单 closeDialogForm(formName) { //重置表单的校验 this.$refs[formName].resetFields(); //清空 this.studentForm.sno = ""; this.studentForm.name = ""; this.studentForm.gender = ""; this.studentForm.birthday = ""; this.studentForm.mobile = ""; this.studentForm.email = ""; this.studentForm.address = ""; this.studentForm.image = "", this.studentForm.imageUrl = "", //关闭 this.dialogVisible = false; //初始化isView和isEdit值 this.isEdit = false; this.isView = false; }, //选择学生头像后点击确定后触发的事件 uploadPicturePost(file) { //定义that let that = this; //定义一个FormData类 let fileReq = new FormData(); //把照片穿进去 fileReq.append('avatar', file.file); //使用Axios发起Ajax请求 axios( { method: 'post', url: that.baseURL + 'upload/', data: fileReq } ).then(res => { // 根据code判断是否成功 if (res.data.code === 1) { //把照片给image that.studentForm.image = res.data.name; //拼接imageurl that.studentForm.imageUrl = that.baseURL + "media/" + res.data.name; } else { //失败的提示! that.$message.error(res.data.msg); } }).catch(err => { console.log(err); that.$message.error("上传头像出现异常!"); }) }, uploadExcelPost(file) { let that = this //实例化一个formdata //定义一个FormData类 let fileReq = new FormData(); //把照片穿进去 fileReq.append('excel', file.file); //使用Axios发起Ajax请求 axios( { method: 'post', url: that.baseURL + 'excel/import/', data: fileReq } ).then(res => { // 根据code判断是否成功 if (res.data.code === 1) { //把照片给image that.students = res.data.data; //计算总共多少条 that.total = res.data.data.length; //分页 that.getPageStudents(); //弹出框体显示结果 this.$alert('本次导入完成! 成功:' + res.data.success +'失败:'+ res.data.error , '导入结果展示', { confirmButtonText: '确定', callback: action => { this.$message({ type: 'info', message: "本次导入失败数量为:" + res.data.error + ",具体的学号:"+res.data.errors, }); } }); //把失败明细打印 console.log("本次导入失败数量为:" + res.data.error + ",具体的学号:"); console.log(res.data.errors); } else { //失败的提示! that.$message.error(res.data.msg); } }).catch(err => { console.log(err); that.$message.error("上传Excel出现异常!"); }) }, exportToExcel(){ let that = this axios.get(that.baseURL + 'excel/export/') .then(res=>{ if(res.data.code ===1){ //拼接excel 的完整URL let url = that.baseURL + 'media/'+ res.data.name; //下载 window.open(url); } else { that.$message.error("导出Excel出现异常!"); } }) .catch(err=>{ console.log(err); }); }, //分页时修改每页的行数 handleSizeChange(size) { //修改当前每页数据行数 this.pagesize = size; //数据重新分页 this.getPageStudents(); }, //调整当前的页码 handleCurrentChange(pageNumber) { //修改当前的页码 this.currentpage = pageNumber; //数据重新分页 this.getPageStudents(); }, //选择复选框时触发的操作 handleSelectionChange(data) { this.selectStudents = data; console.log(data); }, }, })
1.3 index.css样式
html,body,#app,.el-container{ margin: 0px; padding:0px; height: 100%; } .el-header { background-color: #b3c0d1; color: #333; text-align: left; line-height: 80px; font-size:32px; font-weight: bold; } .el-footer { background-color: #b3c0d1; color: #333; text-align: center; line-height: 30px; } .el-aside { background-color: #d3dce6; color: #333; text-align: center; line-height: 200px; } .el-dialog .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .el-dialog .avatar-uploader .el-upload:hover { border-color: #409EFF; } .el-dialog .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .el-dialog .avatar { width: 178px; height: 178px; display: block; }
2. 后端代码:
2.1 设计模型类
from django.db import models # Create your models here. # Student: 学号,姓名,性别,出生日期,手机号码,邮箱地址,家庭住址,照片 class Student(models.Model): gender_choices = (('男', '男'), ('女', '女')) sno = models.IntegerField(db_column="SNo", primary_key=True, null=False) # 学号,不允许为空,主键 name = models.CharField(db_column="SName", max_length=100, null=False) # 姓名,最长100个字符,不允许为空 gender = models.CharField(db_column="Gender", max_length=100, choices=gender_choices) # 性别,选项选择 birthday = models.DateField(db_column="Birthday", null=False) # 出生日期,不允许为空 mobile = models.CharField(db_column="Mobile", max_length=100) # 手机号码, email = models.CharField(db_column="Email", max_length=100) # 邮箱地址 address = models.CharField(db_column="Address", max_length=200) # 家庭住址 image = models.CharField(db_column="Image", max_length=200, null=True) # 照片 # 在默认情况下,生成的表名:App_class, 如果要自定义 ,需要使用Class Meta来自定义 class Meta: managed = True db_table = "Student" # __str__方法 def __str__(self): return "学号:%s\t姓名:%s\t性别:%s" % (self.sno, self.name, self.gender)
2.2配置全局url信息:
from django.contrib import admin from django.urls import path from student import views from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('students/', views.get_students), # 获取所有学生信息的接口 path('students/query/', views.query_students), # 查询学生信息的接口 path('sno/check/', views.is_exists_sno), # 校验学号是否存在 path('student/add/', views.add_student), # 添加学生信息的接口 path('student/update/', views.update_student), # 修改学生信息的接口 path('student/delete/', views.delete_student), # 删除学生信息的接口 path('students/delete/', views.delete_students), # 删除学生信息的接口 path('upload/', views.upload), # 上传文件的接口 path('excel/import/', views.import_students_excel), # 导入Excel文件 path('excel/export/', views.export_student_excel), # 导出Excel文件 ] # 添加这行--- 允许所有的media文件被访问 urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
2.3配置view视图信息
# 引入Student的类 from student.models import Student # 引入JsonResponse模块 from django.http import JsonResponse # 导入json模块 import json # 导入Q查询 from django.db.models import Q # 导入uuid类 import uuid # 导入哈希库 import hashlib # 导入Setting from django.conf import settings # 导入os import os # 引入处理Excel模块 import openpyxl # Create your views here. def get_students(request): """获取所有学生的信息""" try: # 使用ORM获取所有学生信息 并把对象转为字典格式 obj_students = Student.objects.all().values() # 把外层的容器转为List students = list(obj_students) # 返回 return JsonResponse({'code': 1, 'data': students}) except Exception as e: # 如果出现异常,返回 return JsonResponse({'code': 0, 'msg': "获取学生信息出现异常,具体错误:" + str(e)}) def query_students(request): """查询学生信息""" # 接收传递过来的查询条件--- axios默认是json --- 字典类型('inputstr')-- data['inputstr'] data = json.loads(request.body.decode('utf-8')) try: # 使用ORM获取满足条件的学生信息 并把对象转为字典格式 obj_students = Student.objects.filter(Q(sno__icontains=data['inputstr']) | Q(name__icontains=data['inputstr']) | Q(gender__icontains=data['inputstr']) | Q( mobile__icontains=data['inputstr']) | Q(email__icontains=data['inputstr']) | Q( address__icontains=data['inputstr'])).values() # 把外层的容器转为List students = list(obj_students) # 返回 return JsonResponse({'code': 1, 'data': students}) except Exception as e: # 如果出现异常,返回 return JsonResponse({'code': 0, 'msg': "查询学生信息出现异常,具体错误:" + str(e)}) def is_exists_sno(request): """判断学号是否存在""" # 接收传递过来的学号 data = json.loads(request.body.decode('utf-8')) # 进行校验 try: obj_students = Student.objects.filter(sno=data['sno']) if obj_students.count() == 0: return JsonResponse({'code': 1, 'exists': False}) else: return JsonResponse({'code': 1, 'exists': True}) except Exception as e: return JsonResponse({'code': 0, 'msg': "校验学号失败,具体原因:" + str(e)}) def add_student(request): """添加学生到数据库""" # 接收前端传递过来的值 data = json.loads(request.body.decode("utf-8")) try: # 添加到数据库 obj_student = Student(sno=data['sno'], name=data['name'], gender=data['gender'], birthday=data['birthday'], mobile=data['mobile'], email=data['email'], address=data['address'], image=data['image']) # 执行添加 obj_student.save() # 使用ORM获取所有学生信息 并把对象转为字典格式 obj_students = Student.objects.all().values() # 把外层的容器转为List students = list(obj_students) # 返回 return JsonResponse({'code': 1, 'data': students}) except Exception as e: return JsonResponse({'code': 0, 'msg': "添加到数据库出现异常,具体原因:" + str(e)}) def update_student(request): """修改学生到数据库""" # 接收前端传递过来的值 data = json.loads(request.body.decode("utf-8")) try: # 查找到要修改的学生信息 obj_student = Student.objects.get(sno=data['sno']) # 依次修改 obj_student.name = data['name'] obj_student.gender = data['gender'] obj_student.birthday = data['birthday'] obj_student.mobile = data['mobile'] obj_student.email = data['email'] obj_student.address = data['address'] obj_student.image = data['image'] # 保存 obj_student.save() # 使用ORM获取所有学生信息 并把对象转为字典格式 obj_students = Student.objects.all().values() # 把外层的容器转为List students = list(obj_students) # 返回 return JsonResponse({'code': 1, 'data': students}) except Exception as e: return JsonResponse({'code': 0, 'msg': "修改保存到数据库出现异常,具体原因:" + str(e)}) def delete_student(request): """删除一条学生信息""" # 接收前端传递过来的值 data = json.loads(request.body.decode("utf-8")) try: # 查找到要修改的学生信息 obj_student = Student.objects.get(sno=data['sno']) # 删除 obj_student.delete() # 使用ORM获取所有学生信息 并把对象转为字典格式 obj_students = Student.objects.all().values() # 把外层的容器转为List students = list(obj_students) # 返回 return JsonResponse({'code': 1, 'data': students}) except Exception as e: return JsonResponse({'code': 0, 'msg': "删除学生信息写入数据库出现异常,具体原因:" + str(e)}) def delete_students(request): """批量删除学生信息""" # 接收前端传递过来的值 data = json.loads(request.body.decode("utf-8")) try: # 遍历传递的集合 for one_student in data['student']: # 查询当前记录 obj_student = Student.objects.get(sno=one_student['sno']) # 执行删除 obj_student.delete() # 使用ORM获取所有学生信息 并把对象转为字典格式 obj_students = Student.objects.all().values() # 把外层的容器转为List students = list(obj_students) # 返回 return JsonResponse({'code': 1, 'data': students}) except Exception as e: return JsonResponse({'code': 0, 'msg': "批量删除学生信息写入数据库出现异常,具体原因:" + str(e)}) def upload(request): """接收上传的文件""" # 接收上传的文件 rev_file = request.FILES.get('avatar') # 判断,是否有文件 if not rev_file: return JsonResponse({'code': 0, 'msg': '图片不存在!'}) # 获得一个唯一的名字: uuid +hash new_name = get_random_str() # 准备写入的URL file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1]) # 开始写入到本次磁盘 try: f = open(file_path, 'wb') # 多次写入 for i in rev_file.chunks(): f.write(i) # 要关闭 f.close() # 返回 return JsonResponse({'code': 1, 'name': new_name + os.path.splitext(rev_file.name)[1]}) except Exception as e: return JsonResponse({'code': 0, 'msg': str(e)}) def get_random_str(): # 获取uuid的随机数 uuid_val = uuid.uuid4() # 获取uuid的随机数字符串 uuid_str = str(uuid_val).encode('utf-8') # 获取md5实例 md5 = hashlib.md5() # 拿取uuid的md5摘要 md5.update(uuid_str) # 返回固定长度的字符串 return md5.hexdigest() def import_students_excel(request): """从Excel批量导入学生信息""" # ========1. 接收Excel文件存储到Media文件夹 ======= rev_file = request.FILES.get('excel') # 判断,是否有文件 if not rev_file: return JsonResponse({'code': 0, 'msg': 'Excel文件不存在!'}) # 获得一个唯一的名字: uuid +hash new_name = get_random_str() # 准备写入的URL file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1]) # 开始写入到本次磁盘 try: f = open(file_path, 'wb') # 多次写入 for i in rev_file.chunks(): f.write(i) # 要关闭 f.close() except Exception as e: return JsonResponse({'code': 0, 'msg': str(e)}) # ====== 2. 读取存储在Media文件夹的数据 ===== ex_students = read_excel_dict(file_path) # ====3. 把读取的数据存储到数据库 ===== # 定义几个变量: success: error: errors success = 0 error = 0 error_snos = [] # 开始遍历 for one_student in ex_students: try: obj_student = Student.objects.create(sno=one_student['sno'], name=one_student['name'], gender=one_student['gender'], birthday=one_student['birthday'], mobile=one_student['mobile'], email=one_student['email'], address=one_student['address']) # 计数 success += 1 except: # 如果失败了 error += 1 error_snos.append(one_student['sno']) # 4. 返回--导入信息(成功:5,失败:4--(sno)),所有学生 obj_students = Student.objects.all().values() students = list(obj_students) return JsonResponse({'code': 1, 'success': success, 'error': error, 'errors': error_snos, 'data': students}) def export_student_excel(request): """到处数据到excel""" # 获取所有的学生信息 obj_students = Student.objects.all().values() # 转为List students = list(obj_students) # 准备名称 excel_name = get_random_str() + ".xlsx" # 准备写入的路劲 path = os.path.join(settings.MEDIA_ROOT, excel_name) # 写入到Excel write_to_excel(students, path) # 返回 return JsonResponse({'code': 1, 'name': excel_name}) def read_excel_dict(path: str): """读取Excel数据,存储为字典 --- [{},{},{},]""" # 实例化一个wrokbook workbook = openpyxl.load_workbook(path) # 实例化一个sheet sheet = workbook['student'] # 定义一个变量存储最终的数据--[] students = [] # 准备key keys = ['sno', 'name', 'gender', 'birthday', 'mobile', 'email', 'address'] # 遍历 for row in sheet.rows: # 定义一个临时的字典 temp_dict = {} # 组合值和key for index, cell in enumerate(row): # 组和 temp_dict[keys[index]] = cell.value # 附加到list中 students.append(temp_dict) # 返回 return students def write_to_excel(data: list, path: str): """把数据库写入到Excel""" # 实例化一个workbook workbook = openpyxl.Workbook() # 激活一个sheet sheet = workbook.active # 为sheet命名 sheet.title = 'student' # 准备keys keys = data[0].keys() # 准备写入数据 for index, item in enumerate(data): # 遍历每一个元素 for k, v in enumerate(keys): sheet.cell(row=index + 1, column=k + 1, value=str(item[v])) # 写入到文件 workbook.save(path)
2.4 建立一个test.py文件自测一下
import openpyxl def read_excel_dict(path: str): """读取Excel数据,存储为字典 --- [{},{},{},]""" # 实例化一个wrokbook workbook = openpyxl.load_workbook(path) # 实例化一个sheet sheet = workbook['student'] # 定义一个变量存储最终的数据--[] students = [] # 准备key keys = ['sno', 'name', 'gender', 'birthday', 'mobile', 'email', 'address'] # 遍历 for row in sheet.rows: # 定义一个临时的字典 temp_dict = {} # 组合值和key for index, cell in enumerate(row): # 组和 temp_dict[keys[index]] = cell.value # 附加到list中 students.append(temp_dict) # 返回 return students def write_to_excel(data: list, path: str): """把数据库写入到Excel""" # 实例化一个workbook workbook = openpyxl.Workbook() # 激活一个sheet sheet = workbook.active # 为sheet命名 sheet.title = 'student' # 准备keys keys = data[0].keys() # 准备写入数据 for index in range(0, len(data)): # 遍历每一个元素 for cell in range(0, len(data[index])): sheet.cell(row=index + 1, column=cell + 1, value=str(data[index][keys[cell]])) # 写入到文件 workbook.save(path) if __name__ == '__main__': path = "D:\student01.xlsx" # 调用函数! students = read_excel_dict(path) # 输出 print(students)
后端目录结构:
更多相关内容 -
Django开发的一个简单的员工管理系统源码.zip
2022-05-08 14:26:43Django开发的一个简单的员工管理系统源码 Django开发的一个简单的员工管理系统源码 Django开发的一个简单的员工管理系统源码 Django开发的一个简单的员工管理系统源码 Django开发的一个简单的员工管理系统... -
python3+django2开发一个简单的人员管理系统过程详解
2020-09-19 00:24:53主要介绍了python3+django2开发一个简单的人员管理系统过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
基于DJango开发的仓库管理系统源码.zip
2022-05-08 13:00:46基于DJango开发的仓库管理系统,软件架构:python 3.5、django 2.2、MySQL 基于DJango开发的仓库管理系统,软件架构:python 3.5、django 2.2、MySQL 基于DJango开发的仓库管理系统,软件架构:python 3.5、... -
Django开发的员工管理综合系统源码.zip
2022-05-08 15:10:22Django开发的员工管理综合系统源码 Django开发的员工管理综合系统源码 Django开发的员工管理综合系统源码 Django开发的员工管理综合系统源码 Django开发的员工管理综合系统源码 Django开发的员工管理综合系统... -
一个用Python + Django开发的学生管理系统源码.zip
2022-05-08 14:25:29一个用Python + Django开发的学生管理系统源码 一个用Python + Django开发的学生管理系统源码 一个用Python + Django开发的学生管理系统源码 一个用Python + Django开发的学生管理系统源码 一个用Python + ... -
django实现的一个图书管理系统源码.zip
2022-05-08 14:00:56使用django实现的一个图书管理系统,可以进行借书,还书,后台登录,多用户借书功能。 使用django实现的一个图书管理系统,可以进行借书,还书,后台登录,多用户借书功能。 使用django实现的一个... -
Python基于Django框架实现的一个学生信息管理系统源码.zip
2022-05-08 13:36:46Python基于Django框架实现的一个学生信息管理系统源码 Python基于Django框架实现的一个学生信息管理系统源码 Python基于Django框架实现的一个学生信息管理系统源码 Python基于... -
django-minicms:Django开发简易的内容管理系统
2021-03-11 17:55:02django-minicms Django开发简易的内容管理系统自强学堂实战教程,每天提交一次代码,直至项目完成。最终会开发成一个内容管理系统,某些新闻发布网站,博客文章管理等 -
python-django-员工信息管理系统.rar
2022-04-13 20:18:09实现了增删改查等基本操作(基本内容学习参考) 运行环境:python 3.9 django==3.24 mysql 8.0 开发环境:Pycharm -
python + django + mysql开发的高校疫情 防控管理系统
2022-05-17 21:24:16python + django + mysql开发的高校疫情 防控管理系统 -
Python+Django开发的一个类知识库和在线图书馆的系统源码.zip
2022-05-08 13:55:50本电子文档管理系统是基于Python+Django开发的一个类知识库和在线图书馆的开源系统 本电子文档管理系统是基于Python+Django开发的一个类知识库和在线图书馆的开源系统 本电子文档管理系统是基于Python+Django... -
基于Django开发的企业管理信息系统源码.zip
2022-05-08 12:47:54基于Django开发的企业管理信息系统,包含了OA、销售管理、采购管理、库存管理、项目管理、文档管理以及组织管理模块。 基于Django开发的企业管理信息系统,包含了OA、销售管理、采购管理、库存管理、项目... -
使用Django框架开发的企业OA管理系统源码.zip
2022-05-08 14:12:39使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 ... -
Django客户管理系统源码.zip
2022-05-08 14:11:39Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统... -
python3.6+django2.0开发一套学员管理系统
2020-12-23 19:22:552.在demo项目目录下新建目录static,并在settings.py中追加代码: STATICFILES_DIRS=(os.path.join(BASE_DIR, 'static'),) 3.在setting.py中添加模板路径: TEMPLATES = [ { 'BACKEND': '...', ... -
Python+Django+VUE后台管理系统
2022-01-19 12:51:50此Python+Django+VUE后台管理系统。包括的功能是用户管理----用户组管理的 增删该查功能。其中mysql数据库表的信息user_group.sql,也放到项目文件夹里了。 -
Python-ERUManager是一个基于Django框架开发的一款远程主机管理系统
2019-08-10 05:43:26ERU-Manager 是一个基于 Django 框架开发的一款 CMDB 管理系统,功能主要包含: 管理系统管理的客户主机列表, 动态显示客户机状态信息, 远程指令操作指定客户机, 主机与客户机之间的文件传输以及完善的后台管理系统。 -
基于 Django + Vue 实现的 用户信息管理系统
2022-01-02 19:46:47可修改用户信息,头像,个性签名等 -
基于Django框架的管理系统的设计与开发
2020-07-20 18:31:03以新疆昭苏地区的马产业为例搭建了一个基于Django框架的马匹竞拍管理系统。该系统将昭苏马产业与信息技术相结合,采用Django网页开发框架、Bootstrap响应式网页开发技术、Python语言和MTV的设计模式实现了商品信息... -
SilverFox是一个采用Django和基于Bootstrap开发的后台管理系统
2019-08-12 06:18:59SilverFox是一个采用Django和基于Bootstrap开发的Gentelella模板实现的KBEngine服务器后台管理系统 -
用Django写的一个简单的OA办公系统源码.zip
2022-05-08 14:51:34用Django写的一个简单的OA办公系统源码 用Django写的一个简单的OA办公系统源码 用Django写的一个简单的OA办公系统源码 用Django写的一个简单的OA办公系统源码 用Django写的一个简单的OA办公系统源码 用... -
使用django实现一个代码发布系统
2021-01-20 06:20:33一 前期说明: ...3角色分为管理员,开发,运维,测试,产品几个角色,每个角色返回不同的页面,利用rbac基于角色去实现不同的权限 4 管理员拥有所有权限,可以添加编辑,删除所有的东西 5 分页功能和快速搜索 -
Django admin实现图书管理系统菜鸟级教程完整实例
2021-01-20 04:12:42用Django实现管理书籍的系统,并能在前台界面对书籍进行增删查改,筛选,分页,以及批量查询修改功能. 准备工作 #准备好你的数据库模型思维导图 0.新建一个Django项目,起名为books,并且同时新建一个应用book11 1.... -
Django项目开发:图书后台管理系统
2021-10-30 19:27:10大家好,我是梓栋,今天我给大家分享一个Django入门级开发项目—图书后台管理系统,想要源码资料的小伙伴,请关注微信公众号:梓栋Code,回复 “009”获取! 一.项目介绍 1.管理员登录注册 (1)注册页面 (2)...大家好,我是梓栋,今天我给大家分享一个Django入门级开发项目—图书后台管理系统,想要源码资料的小伙伴,请关注微信公众号:梓栋Code,回复 “009”获取!
一.项目介绍
1.管理员登录注册
(1)注册页面
(2)登录页面
2.出版社管理页面
(1) 添加出版社
(2)出版社列表
(3)修改出版社
(4)删除出版社
3.图书管理页面
(1)添加图书
(2)图书列表
(3) 修改图书
(4)删除图书
4.作者管理页面
(1)添加作者
(2)作者列表
(3)修改作者
(4)删除作者
5.用户管理页面
(1)添加用户
(2)用户列表
(3)修改用户
(4)删除用户
6.后台数据展示页
二、数据库设计
这个教程的数据库主要设计了6个表,管理员表、出版社表、图书表、图书图片表、作者表、用户表。
这几个数据库表的关系如下:
想要项目源码资料的小伙伴,请关注微信公众号:梓栋Code,回复 “009”获取!
-
Django快速开发web管理系统(一) —— 搭建环境
2020-04-22 21:21:02Django开发 —— 搭建环境环境参数环境配置一、pycharm创建django项目二、在本地mongodb创建数据库三、修改django配置,创建app四、自行配置数据库处理过程 环境参数 python:3.7 django:通过pip安装,过程省略 db...环境参数
python:3.7
django:通过pip安装,过程省略
db:mongodb,安装过程省略环境配置
一、pycharm创建django项目
1)打开pycharm,点击new project。
目录结构如下所示。
二、在本地mongodb创建数据库
目录结构如下所示。
三、修改django配置,创建app
1)pip install mongoengine
2)进入settings.py,修改代码如下:
DATABASES = { 'default': { 'ENGINE': None, } } from mongoengine import connect connect('mydb')
3)创建app
先创建一个apps文件夹,因为你的app有可能不止一个,所以放在一个文件夹里方便管理。
创建好apps文件夹后,还需要创建一个文件夹,此文件夹就是你的app,文件名称是你的app名称。
pycharm上点击此按钮。
输入命令,创建成功。
结果如图所示。
四、自行配置数据库处理过程
我不喜欢用 django 自带的数据库处理模块,更喜欢 java 那种:自己去写相关操作。
所以本人建了一个类专门处理数据库相关操作。
1)创建相关目录。
2)代码from pymongo import MongoClient from pymongo.database import Database class MongoDB(object): def __init__(self, host='localhost', port=27017, usr=None, pwd=None, db_name='mydb'): self.__host = host self.__port = port self.__userName = usr self.__userPwd = pwd self.__database = db_name self.client: MongoClient = None # 连接mongodb的客户端 self.idpiDataBase: Database = None # 连接智能业务识别的数据库连接 # 初始化客户端 self.__initClient() def __initClient(self): self.close() if self.__userName == "": self.client: MongoClient = MongoClient(host=self.__host, port=self.__port) self.idpiDataBase: Database = self.client[self.__database] # 数据库如果不存在则会创建 else: try: self.client: MongoClient = MongoClient(host=self.__host, port=self.__port) self.idpiDataBase: Database = self.client[self.__database] # 数据库如果不存在则会创建 self.idpiDataBase.authenticate(self.__userName, self.__userPwd) except Exception as e: self.client: MongoClient = MongoClient(host=self.__host, port=self.__port, username=self.__userName, password=self.__userPwd) self.idpiDataBase: Database = self.client[self.__database] def close(self): if self.client is not None: try: self.client.close() except Exception as e: print(f'fail to close mongodb: {e}') finally: self.client = None
3)测试代码是否正确
-
Python基于Django图书管理系统毕业论文源码
2021-06-17 15:34:35人生苦短,我用Python,咱们今天就来分享一个用Python语言开发的基于Django框架的图书管理系统吧。项目前台和后台界面模板都是自己编写,前台采用Bootstrap框架UI,后台EasyUI框架UI,没有采用Django自动生成的那个... -
django信息资产管理系统.7z
2021-10-30 14:09:15信息资产管理系统:基于django框架开发、主要实现企业资产的录入,编辑、导出。还有IP地址管理等 -
Django搭建后台管理系统
2022-02-18 13:52:45搭建后台管理系统,注册登录一个完整的微Web应用软件基本都会有一关管理员管理应用数据的后台管理系统,我们可以通过针对这个管理系统做出一系列的功能,比如菜单,选项,侧边栏,链接等进行数据的管理,也可以网站中的用户数据之类进行维护与更新。
后台管理系统的基本操作
Django配合python的使用可以说是非常友好帮助我们搭建后台管理,包括良好的展示界面。
打开Django的配置文件,这里写入我们的项目应用名称-----smanage
本次总结就是通过django.contrib.admin添加到所创建的Django项目中,并且可以通过django.contrib.auth模块完成用户的认证处理,使用djang.contrib.sessions模块来实现状态保持的操作
setting文件配置时,我们可以先将我们的网站展示为中文
接着打开创建smanage项目,对该项目应用的models.py文件进行数据模型操作
from django.db import models # Create your models here. class Classes(models.Model): classname = models.CharField(max_length=30, verbose_name='班级号') class_price = models.IntegerField(verbose_name='班费') classroom = models.IntegerField(verbose_name='教室号') class Meta: # db_table = 'class' verbose_name_plural = verbose_name = '班级表' class Student(models.Model): name = models.CharField(max_length=20, verbose_name='姓名') age = models.IntegerField(verbose_name='年龄') classes = models.ForeignKey(Classes, on_delete=models.CASCADE, verbose_name='班级号') phone = models.IntegerField(verbose_name='电话') image = models.ImageField(upload_to='staic/', default='staic/8.png', verbose_name='头像') class Meta: verbose_name_plural = verbose_name = '学生表' def __str__(self): return self.name
这里我写的是主表与从表的关系,用到了Foreign
这里的verbose_name就是起别名的意思,并且Classes这个类使用了一个ImageField的属性,它是 用来存入图片做头像之类,括号里的upload_to选项是必填项,使用相对路径,default选项就是如果没有存入图片,系统将选择默认图片进行存入。
生成迁移文件的两步骤
在终端进行输入 python manage.py makemigrations 和 python manage.py migrate 按顺序
下一步再对我们的apps.py文件和admin.py文件进行操作
在这里对我们的后台系统显示出来,这SmanageConfig类继承了AppConfig,这里用到了default_auto_field,就是ID字段自增,用verbose_name命名为学生管理系统
from django.contrib import admin # Register your models here. from .models import Classes, Student @admin.register(Student) class StudentAdmin(admin.ModelAdmin): list_display = ('name', 'age', 'phone', 'image', 'classes_id') @admin.register(Classes) class ClassesAdmin(admin.ModelAdmin): list_display = ('classname', 'class_price', 'classroom') # 展示 list_editable = ('class_price', 'classroom') # 负责修改 list_filter = ('classname',) list_per_page = 4 # 分页 ordering = ['-classroom', 'classname'] # 优先级排序
首先我们要先进行注册用户到数据库,并且给该用户设置有权限访问admin界面,并且可以管理这个数据模型
这里用到了装饰器进行注册了Student和Classes,并将它们封装成了类
在admin.py文件我们主要对字段的操作,展示,添加,修改,删除等基本操作
list_display:数据的展示、list_editable:数据的修改
list_filter:条件过滤
进行一个筛选功能
list_per_page:分页功能
ordering:优先级排序
本次总结到这里结束