课程表管理系统
1.学生/教师用户登录界面
2.首页
3.课程详细
4.保存csv功能
5.管理员登录界面
6.管理员后台界面
7.代码详解
8.项目部署
854771076/course (github.com)
点击已有课程,可弹出课程详细数据。
点击保存csv按钮,可下载当前显示课表的csv格式文档。
管理员通过后台可以对老师、学生、班级等数据表进行增删改查功能,同时管理员后台首页可以实时的对每个班级/老师的课程进行安排,还有简单的筛选搜索功能、导出csv功能、新增/删除/修改课表信息功能。
数据库建模
根据需求分析,总共建立了老师表、班级表、学生表、教室表、课程总表
表之间的关系
学生表和班级表是一对多的关系,
课程表和老师表是一对多的关系,
课程表班级表是一对多的关系,
课程表教室表是一对多的关系。
#models.py
from django.db import models
from django.utils import timezone
# Create your models here.
#老师表
class Teacher(models.Model):
id=models.BigAutoField(primary_key=True,blank=False)
teacher_name = models.CharField(max_length=255,verbose_name='教师姓名')
teacher_num = models.CharField(max_length=255, blank=True, null=True,verbose_name='教师工号')
password=models.CharField(max_length=200,verbose_name='密码')
teacher_level = models.IntegerField(verbose_name='教师等级')
sex = models.IntegerField(verbose_name='性别',help_text='1 男 2 女')
age = models.IntegerField(blank=True, null=True,verbose_name='年龄')
phone = models.CharField(max_length=255,verbose_name='手机号')
birthday = models.CharField(max_length=255, blank=True, null=True,verbose_name='出生年月')
email = models.CharField(max_length=255, blank=True, null=True,verbose_name='教师邮箱')
school = models.CharField(max_length=255, blank=True, null=True,verbose_name='毕业院校')
department = models.CharField(max_length=255, blank=True, null=True,verbose_name='毕业院校院系')
major = models.CharField(max_length=255, blank=True, null=True,verbose_name='毕业院校专业')
education = models.CharField(max_length=255, blank=True, null=True,verbose_name='学历')
def __str__(self):
return self.teacher_name
class Meta:
verbose_name_plural='老师表'
# managed = False
db_table = 'teacher'
#班级表
class BasicClass(models.Model):
id=models.BigAutoField(primary_key=True,blank=False)
class_name = models.CharField(max_length=200,verbose_name='班级名')
class_cate = models.IntegerField(blank=True, null=True,verbose_name='班级分类',help_text='0 五天全日制 1 六天全日制 2预科班 3 周末班')
start_time = models.DateTimeField(verbose_name='开班时间')
class_status = models.IntegerField(blank=True, null=True,verbose_name='班级状态',help_text='0 正常 1禁用')
description = models.CharField(max_length=200, blank=True, null=True,verbose_name='备注')
def __str__(self):
return self.class_name
class Meta:
verbose_name_plural='班级表'
# managed = False
db_table = 'basic_class'
#学生表
class Student(models.Model):
id=models.BigAutoField(primary_key=True,blank=False)
student_name = models.CharField(max_length=200,verbose_name='学生姓名')
password=models.CharField(max_length=200,verbose_name='密码')
student_num = models.CharField(max_length=255, null=False,verbose_name='学号')
#学生表和班级表是一对多的关系,这里建立外键
Class =models.ForeignKey(BasicClass, verbose_name='班级', on_delete=models.CASCADE)
add_time = models.DateTimeField(verbose_name='加入班级时间')
student_status = models.IntegerField(verbose_name='学生状态',help_text='0正常 1 请假 2 休学 3 退学')
sex = models.IntegerField(blank=True, null=True,verbose_name='性别')
age = models.IntegerField(blank=True, null=True,verbose_name='年龄')
birthday = models.CharField(max_length=200, blank=True, null=True,verbose_name='出生年月日')
student_email = models.CharField(max_length=200, blank=True, null=True,verbose_name='邮箱')
student_school = models.CharField(max_length=200, blank=True, null=True,verbose_name='院校')
student_department = models.CharField(max_length=200, blank=True, null=True,verbose_name='院系')
student_major = models.CharField(max_length=200, blank=True, null=True,verbose_name='专业')
student_school_class = models.CharField(max_length=200, blank=True, null=True,verbose_name='在校班级')
student_education = models.CharField(max_length=200, blank=True, null=True,verbose_name='学历')
phone = models.CharField(max_length=200,verbose_name='手机号')
qq_number = models.CharField(max_length=200, blank=True, null=True,verbose_name='qq号')
wechart_number = models.CharField(max_length=200, blank=True, null=True,verbose_name='微信号')
idcard = models.CharField(max_length=200, blank=True, null=True,verbose_name='身份证号')
emergency_name = models.CharField(max_length=200, blank=True, null=True,verbose_name='紧急联系人姓名')
emergency_phone = models.CharField(max_length=200, blank=True, null=True,verbose_name='紧急联系人电话')
family_address = models.CharField(max_length=200, blank=True, null=True,verbose_name='家庭住址')
now_address = models.CharField(max_length=200, blank=True, null=True,verbose_name='现在住址')
guarder = models.CharField(max_length=200, blank=True, null=True,verbose_name='监护人')
guarder_phone = models.CharField(max_length=200, blank=True, null=True,verbose_name='监护人电话')
description = models.CharField(max_length=200, blank=True, null=True,verbose_name='备注')
def __str__(self):
return self.student_name
class Meta:
verbose_name_plural='学生表'
# managed = False
db_table = 'student'
#教室表
class Room(models.Model):
id=models.BigAutoField(primary_key=True,blank=False)
room_name = models.CharField(max_length=200,verbose_name='教室名')
room_count = models.IntegerField(blank=True, null=True,verbose_name='教室容量')
room_status = models.IntegerField(blank=True, null=True,verbose_name='教室状态',help_text='0教室空闲 1教室禁用',default=0)
description = models.CharField(max_length=200, blank=True, null=True,verbose_name='描述')
def __str__(self):
return self.room_name
class Meta:
verbose_name_plural='教室表'
# managed = False
db_table = 'rooms'
#课程表
class CourseWeekData(models.Model):
id=models.BigAutoField(primary_key=True,blank=False)
week = models.IntegerField(verbose_name="周数",default=0)
Section=models.IntegerField(verbose_name="节次",null=False)
subject=models.CharField(verbose_name="课程名", max_length=50,null=False)
day=models.IntegerField(verbose_name="星期",null=False)
#课程表和老师表、班级表、教室表都是一对多的关系
teacher=models.ForeignKey(Teacher, verbose_name='老师', on_delete=models.CASCADE)
Class=models.ForeignKey(BasicClass, verbose_name='班级', on_delete=models.CASCADE)
room=models.ForeignKey(Room, verbose_name='教室', on_delete=models.CASCADE)
def __str__(self):
return str(self.week)
class Meta:
verbose_name_plural='周课表数据'
db_table='course_weekdata'
后台管理
后台管理使用的Django的第三方ui库simpleui来美化后台界面,参数配置如下。
#settings.py
#后台logo
SIMPLEUI_LOGO=r'/static/favicon.ico'
#关闭simpleui广告
SIMPLEUI_HOME_INFO = False
#后台首页
SIMPLEUI_HOME_PAGE = '/root_index'
INSTALLED_APPS = [
'simpleui',#注册simpleuiAPP,需要放到最前面
'django.contrib.contenttypes',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'courseIndex',#注册courseIndexAPP
]
list_display是后台管理界面需要显示出的字段
search_fields是后台参与搜索的字段
ordering是参与排序的字段
#admin.py
from django.contrib import admin
# Register your models here.
from .models import *
#后台名字
admin.site.site_title = "后台管理"
admin.site.site_header = "排课系统"
#注册老师表后台管理功能
@admin.register(Teacher)
class TeacherAdmin(admin.ModelAdmin):
exclude = []
list_display=['teacher_num','teacher_name']
search_fields=['teacher_name']
#注册课程表后台管理功能
@admin.register(CourseWeekData)
class CourseWeekDataAdmin(admin.ModelAdmin):
exclude = []
list_display = ['id','subject','week','teacher','Class','room','day','Section']
ordering=['week','day','Section']
search_fields=['week','teacher']
#注册班级表后台管理功能
@admin.register(BasicClass)
class BasicClassAdmin(admin.ModelAdmin):
exclude = []
search_fields=['class_name']
#注册教室表后台管理功能
@admin.register(Room)
class RoomAdmin(admin.ModelAdmin):
exclude = []
search_fields=['room_name']
#注册学生表后台管理功能
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display=['student_num','student_name']
exclude = []
search_fields=['student_name']
项目路由
#course.urls.py
#主路由
from django.contrib import admin
from django.urls import path,include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
#管理员后台
path('admin/', admin.site.urls,name='admin'),
#拼接courseIndex应用所有路由
path('', include("courseIndex.urls")),
]+ static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
#courseIndex路由
#courseIndex.urls.py
from django.urls import path
from . import views
from django.conf.urls import url
app_name='courseIndex'
urlpatterns = [
#管理员首页
path('root_index', views.root_index,name='root_index'),
#获取当前可带课的老师数据
path('getteacher',views.getteacher,name='getteacher' ),
#获取当前空闲教室数据
path('getroom',views.getroom,name='getroom' ),
#获取当前无课班级数据
path('getclasses',views.getclasses,name='getclasses' ),
#获取当前课表数据
path('getdata',views.getdata,name='getdata' ),
#添加课表详细接口
path('adddata',views.adddata,name='adddata' ),
#删除课表详细接口
path('deldata',views.deldata,name='deldata' ),
#保存当前课表数据
path('savedata',views.savedata,name='savedata' ),
#首页
path('', views.index,name='index'),
#登录页
path('login', views.Login.as_view(),name='login'),
]
视图函数
课程表数据核心代码
#获取课程表数据
def getdata(request):
#获取当前周次
week = int(request.GET.get('week', 1))
#筛选条件
cid = request.GET.get('cid', '')#班级id
tid = request.GET.get('tid', '')#老师id
#初始化课程表
'''
[[[], [], [], [], [], []],
[[], [], [], [], [], []],
[[], [], [], [], [], []],
[[], [], [], [], [], []],
[[], [], [], [], [], []],
[[], [], [], [], [], []],
[[], [], [], [], [], []]]
是一个7行6列的列表,行代表星期,列代表课程节次,最里面的小列表是为了处理一个时间段有多个班级多门课的情况
'''
li = [[[] for j in range(6)] for i in range(7)]
#如果传入了老师/班级筛选条件,就进行筛选
if cid == '':
courses = CourseWeekData.objects.filter(Q(week=week))
else:
courses = CourseWeekData.objects.filter(Q(week=week) & Q(Class_id=cid))
if tid == '':
pass
else:
courses = courses.filter(teacher_id=tid)
#将每行里的小列表填上查到的课表数据
for course in courses:
li[course.day-1][course.Section-1].append({'id': course.id, 'subject': course.subject, 'teacher': course.teacher.teacher_name, 't_id': course.teacher.id, 'class': course.Class.class_name,
'c_id': course.Class.id, 'room': course.room.room_name, 'r_id': course.room.id, 'week': course.week, 'day': course.day, 'Section': course.Section})
return JsonResponse({"list": li, 'week': week}, json_dumps_params={'ensure_ascii': False})
#保存csv,查询原理同上
def savedata(request):
week = int(request.GET.get('week', 1))
cid = request.GET.get('cid', '')
cname = ''
tid = request.GET.get('tid', '')
li = {f'星期{i+1}': ['' for j in range(6)] for i in range(7)}
if cid == '':
courses = CourseWeekData.objects.filter(Q(week=week))
else:
cname = BasicClass.objects.get(id=cid).class_name
courses = CourseWeekData.objects.filter(Q(week=week) & Q(Class_id=cid))
if tid == '':
pass
else:
courses = courses.filter(teacher_id=tid)
for course in courses:
li[f'星期{course.day}'][course.Section-1] += course.subject+'@' + \
course.teacher.teacher_name+'@' + \
course.Class.class_name+'@'+course.room.room_name+'\n'
#将查询到的课表数据转换为DataFrame对象
df = pd.DataFrame(li)
#改字段名
df.columns = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天']
df.index = [i for i in range(1, 7)]
#生成课表名
name = f'{cname}第{week}周课程表_{datetime.datetime.now().timestamp()}.csv'
#保存至项目media/csv/目录下
df.to_csv(r'media/csv/'+name)
#返回保存路径
return redirect('/media/csv/'+name)
创建虚拟环境
conda create -n course python=3.8
安装项目依赖
#进入项目虚拟环境
conda activate course
#进入项目目录
cd xxx
#安装依赖
pip install -r requirements.txt
修改数据库设置
#进入项目settings.py,修改数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '数据库名',
'USER':'用户名',
'PASSWORD':'密码',
'HOST':'127.0.0.1',
'POST':'3306',
'OPTIONS': {'charset': 'utf8mb4'},
}
}
迁移数据库
#进入项目目录
cd xxx
python manage.py makemigrations
python manage.py migrate
启动项目
python manage.py runserver