django学生管理系统
CourseSys(选课系统项目)
项目目录结构

settings.py
静态资源配置、文件存储配置和继承django自带用户表设置
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'student.mds.AuthMiddleWare' # 登录中间件
]
# 静态资源路径
STATIC_URL = '/static/'
STATICFILES_DIRS = [ # 列表或者元组都行
os.path.join(BASE_DIR, 'static'),
]
# 修改auth用户表
# from django.conf.global_settings import AUTH_USER_MODEL
AUTH_USER_MODEL = 'UserInfo'
# 用户文件目录
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = "/media/"
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
import os
# Create your models here
# 班级表.
class Clas(models.Model):
name = models.CharField(max_length=32, verbose_name='班级名称')
class Meta:
db_table = 'db_class'
# 课程表
class Course(models.Model):
title = models.CharField(max_length=32, verbose_name='课程名称')
credit = models.IntegerField(verbose_name='学分', default=3)
teacher = models.CharField(max_length=32, null=True)
classTime = models.CharField(max_length=32, null=True)
classAddr = models.CharField(max_length=32, null=True)
class Meta:
db_table = 'db_course'
# 创建目录时根据登录人员信息创建文件夹
def user_directory_path(instance, filename): # instance 是当前model类的实例
return os.path.join(instance.username, "avatars", filename)
# 用户表,继承auth.user 和 学生表一对一,在settings表里 设置AUTH_USER_MODEL表名对应此表
class UserInfo(AbstractUser):
avatar = models.ImageField(upload_to=user_directory_path)
stu = models.OneToOneField('student', on_delete=models.CASCADE, null=True)
# 学生表
class Student(models.Model):
sex_choice = (
(0, '女'),
(1, '男'),
(2, '保密')
)
name = models.CharField(max_length=32, verbose_name='姓名', unique=True)
age = models.SmallIntegerField(verbose_name='年龄', default=18)
sex = models.SmallIntegerField(verbose_name='性别', choices=sex_choice)
birthday = models.DateField()
# 一对多关系
clas = models.ForeignKey(to=Clas, on_delete=models.CASCADE)
# 多对多关系
courses = models.ManyToManyField(to=Course, db_table='db_student2course')
# 一对一关系
stu_detail = models.OneToOneField(to='StudentDetail', null=True, on_delete=models.CASCADE)
class Meta:
db_table = 'db_student'
# 学生详情表
class StudentDetail(models.Model):
tel = models.CharField(max_length=11)
addr = models.CharField(max_length=32)
class Meta:
db_table = 'db_stu_detail'
urls.py
总路由
from django.contrib import admin
from django.urls import path, re_path,include
from student import views
urlpatterns = [
path('admin/', admin.site.urls),
# path('login/',views.login),
path('',include('student.urls'))
]
student/urls.py
from django.urls import path, re_path,include
from student import views
urlpatterns = [
# 学生信息增删改查
path('student/',views.student,name='student'),
path('add/',views.stu_add,name='add'),
re_path('delete/(\d+)/', views.delete, name='delete'),
re_path('edit/(\d+)/', views.edit, name='edit'),
# 课程信息增删改查
path('course/',views.course,name='course'),
path('course_add/',views.course_add,name='course_add'),
re_path('course_edit/(\d+)',views.course_edit,name='course_edit'),
re_path('course_delete/(\d+)', views.course_delete, name='course_delete'),
# 批量添加学生信息
path('stu_excel/',views.stu_excel,name='stu_excel'),
# 搜索
path('search/',views.search,name='search'),
# 登录和退出
path('login/',views.login,name='login'),
path('logout/',views.logout,name='logout')
]
用户信息中间件
student.mds.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
class AuthMiddleWare(MiddlewareMixin):
def process_request(self,request):
if request.path in ['/login/']: # 白名单,否则会进入死循环
return
if not request.user.username:
return redirect('/login/')
views.py
from django.shortcuts import render,HttpResponse,redirect
from student import models
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import os
from openpyxl import load_workbook
from django.contrib import auth
# Create your views here.
# 封装的分页函数
def page_func(request,page_obj,get_page):
# 分页器对象,每页10条数据
paginator = Paginator(page_obj, 5)
# 通过前端get请求获取的当前页码
# visit_page_num = int(request.GET.get('page', 1))
visit_page_num = int(get_page)
try:
# 获取当前页面对象
page = paginator.page(visit_page_num)
except EmptyPage: # page=paginator.page(200) 超出页码范围
page = paginator.page(1)
except PageNotAnInteger: # page=paginator.page("zdsds") 当前页码非数字
page = paginator.page(1)
# 当前页数小于等于2时,页码范围(1,2,3,4,5)
if paginator.num_pages < 5:
page_range = range(1,paginator.num_pages+1)
else:
if visit_page_num <= 2:
page_range = range(1, 6)
# 当前页数大于18小于20时,页码范围(16,17,18,19,20)
elif paginator.num_pages >= visit_page_num > paginator.num_pages - 2:
page_range = range(paginator.num_pages - 4, paginator.num_pages + 1)
# 如果当前页码数大于最大页码数
elif visit_page_num > 20:
page_range = range(paginator.num_pages - 4, paginator.num_pages + 1)
# 正常范围内显示5个页码数
else:
page_range = [visit_page_num - 2, visit_page_num - 1, visit_page_num, visit_page_num + 1, visit_page_num + 2]
return paginator,page,page_range,visit_page_num
# 查看学生
def student(request):
stu_list = models.Student.objects.all()
get_page = request.GET.get('page', 1)
paginator,stu_list,page_range,visit_page_num = page_func(request,stu_list,get_page)
return render(request,'index.html',{'stu_list':stu_list, # 当前页面对象
'paginator': paginator, # 分页器对象,获取 数据总数、总页数、页码的列表
'page_range': page_range, # 页码的列表
'visit_page_num': visit_page_num, # 当前页码数
})
# 添加学生
def stu_add(request):
if request.method == 'GET':
# clas = models.Clas.objects.filter(studnet_set)
clas = models.Clas.objects.all()
course = models.Course.objects.all()
return render(request, 'stu_add_edit.html', {'clas':clas, 'course':course})
else:
# 获取要添加的所有数据
stu_list = request.POST.dict()
# 单独获取课程id
course_list = request.POST.getlist('course')
# 删除csrf和课程键值对
del stu_list['csrfmiddlewaretoken']
del stu_list['course']
# 创建学生信息
models.Student.objects.create(**stu_list)
# 根据刚创建的学生信息添加课程
name = stu_list['name']
stu = models.Student.objects.filter(name=name)[0]
stu.courses.set(course_list)
return redirect('student')
# 编辑学生
def edit(request,stu_id):
if request.method == 'GET':
stu = models.Student.objects.filter(id=stu_id)[0]
clas = models.Clas.objects.all()
course = models.Course.objects.all()
return render(request, 'stu_add_edit.html', {'stu_id':stu_id,
'stu':stu,
'clas':clas,
'course':course
})
else:
stu_list = request.POST.dict()
# 单独获取课程id
course_list = request.POST.getlist('course')
# 删除csrf和课程键值对
del stu_list['csrfmiddlewaretoken']
del stu_list['course']
stu = models.Student.objects.filter(id=stu_id)
# 更新学生信息
stu.update(**stu_list)
# 根据学生信息更新课程
stu[0].courses.set(course_list)
return redirect('student')
# 删除学生
def delete(request,stu_id):
models.Student.objects.filter(id=stu_id).delete()
return redirect('/student/')
# 搜索框
def search(request):
if request.method == 'POST':
key_word = request.POST.get('key_word')
cate = request.POST.get('cate')
if cate == 'name':
stu_list = models.Student.objects.filter(name__contains=key_word)
else:
stu_list = models.Student.objects.filter(clas__name__contains=key_word)
get_page = request.GET.get('page', 1)
paginator, stu_list, page_range, visit_page_num = page_func(request, stu_list, get_page)
return render(request, 'index.html', {'stu_list': stu_list, # 当前页面对象
'paginator': paginator, # 分页器对象,获取 数据总数、总页数、页码的列表
'page_range': page_range, # 页码的列表
'visit_page_num': visit_page_num, # 当前页码数
'key_word': key_word
})
# 查看课程
def course(request):
if request.method == 'GET':
course = models.Course.objects.all()
get_page = request.GET.get('page', 1)
paginator, course, page_range, visit_page_num = page_func(request, course, get_page)
return render(request, 'course.html', {'course': course,
'paginator': paginator, # 分页器对象,获取 数据总数、总页数、页码的列表
'page_range': page_range, # 页码的列表
'visit_page_num': visit_page_num, # 当前页码数
})
# 添加课程
def course_add(request):
if request.method == 'GET':
return render(request,'course_add_edit.html')
else:
course_list = request.POST.dict()
del course_list['csrfmiddlewaretoken']
models.Course.objects.create(**course_list)
return redirect('course')
# 编辑课程
def course_edit(request,course_id):
if request.method == 'GET':
cour = models.Course.objects.filter(id=course_id)[0]
print(cour.title)
return render(request,'course_add_edit.html',{'course_id':course_id,
'cour':cour,
})
else:
course_list = request.POST.dict()
del course_list['csrfmiddlewaretoken']
course = models.Course.objects.filter(id=course_id)
course.update(**course_list)
return redirect('course')
# 删除课程
def course_delete(request,course_id):
models.Course.objects.filter(id=course_id).delete()
return redirect('course')
# 批量导入学生信息
def stu_excel(request):
if request.method == 'POST':
file = request.FILES.get('uploadFile')
path = os.path.join('media','files',file.name)
with open(path,'wb') as f:
for line in file:
f.write(line)
# 读取表格数据写入数据库
work = load_workbook(path)
work_sheet = work.worksheets[0]
stu_list = []
for row in work_sheet.iter_rows(min_row=3):
if row[0].value == None:
break
ad = models.StudentDetail.objects.create(addr=row[5].value, tel=row[4].value)
class_id = models.Clas.objects.get(name=row[6].value)
sex = [i[0] for i in models.Student.sex_choice if row[2].value == i[1]]
stu = models.Student(
name=row[0].value,
age=row[1].value,
sex=sex[0],
birthday=row[3].value,
clas_id=class_id.pk,
stu_detail_id=ad.id
)
stu_list.append(stu)
# 批量创建
models.Student.objects.bulk_create(stu_list)
return redirect('student')
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
user = request.POST.get('loginUsername')
pwd = request.POST.get('loginPassword')
auther = auth.authenticate(username=user, password=pwd)
if auther:
# 写session
auth.login(request, auther)
return redirect('student')
else:
return redirect('login')
def logout(request):
auth.logout(request)
return redirect('/login/')
前端页面
base.html
<!DOCTYPE html>
<html>
<head>
{% load static %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>学生管理系统</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all,follow">
<!-- Bootstrap CSS-->
<link rel="stylesheet" href="https://www.jq22.com/jquery/bootstrap-4.2.1.css">
<!-- Font Awesome CSS-->
<link rel="stylesheet" href="https://www.jq22.com/jquery/font-awesome.4.7.0.css">
<!-- Fontastic Custom icon font-->
<link rel="stylesheet" href="{% static 'jquerybootstraphtmoban/css/fontastic.css' %}">
<!-- Google fonts - Roboto -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<!-- jQuery Circle-->
<link rel="stylesheet" href="{% static 'jquerybootstraphtmoban/css/grasp_mobile_progress_circle-1.0.0.min.css' %}">
<!-- Custom Scrollbar-->
<link rel="stylesheet" href="{% static 'jquerybootstraphtmoban/vendor/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css' %}">
<!-- theme stylesheet-->
<link rel="stylesheet" href="{% static 'jquerybootstraphtmoban/css/style.default.css' %}" id="theme-stylesheet">
<!-- Custom stylesheet - for your changes-->
<link rel="stylesheet" href="{% static 'jquerybootstraphtmoban/css/custom.css' %}">
<!-- Favicon-->
<link rel="shortcut icon" href="{% static 'jquerybootstraphtmoban/img/favicon.ico' %}">
<!-- Tweaks for older IEs--><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
{% block css %}
{% endblock %}
</head>
<body>
<!-- Side Navbar -->
<nav class="side-navbar">
<div class="side-navbar-wrapper">
<!-- Sidebar Header -->
<div class="sidenav-header d-flex align-items-center justify-content-center">
<!-- User Info-->
<div class="sidenav-header-inner text-center"><img src="{% static 'jquerybootstraphtmoban/img/avatar-7.jpg' %}" alt="person" class="img-fluid rounded-circle">
<h2 class="h5">Nathan Andrews</h2><span>Web Developer</span>
</div>
<!-- Small Brand information, appears on minimized sidebar-->
<div class="sidenav-header-logo"><a href="index.html" class="brand-small text-center"> <strong>B</strong><strong class="text-primary">D</strong></a></div>
</div>
<!-- Sidebar Navigation Menus-->
<div class="main-menu">
<h5 class="sidenav-heading">Main</h5>
<ul id="side-main-menu" class="side-menu list-unstyled">
<li><a href="{% url 'student' %}"> <i class="icon-home"></i>学生管理 </a></li>
<li><a href="{% url 'course' %}"> <i class="icon-form"></i>课程管理 </a></li>
</ul>
</div>
</div>
</nav>
<div class="page">
<!-- navbar-->
<header class="header">
<nav class="navbar">
<div class="container-fluid">
<div class="navbar-holder d-flex align-items-center justify-content-between">
<div class="navbar-header"><a id="toggle-btn" href="#" class="menu-btn"><i class="icon-bars"> </i></a><a href="index.html" class="navbar-brand">
<div class="brand-text d-none d-md-inline-block"><span>Bootstrap </span><strong class="text-primary">Dashboard</strong></div></a></div>
<ul class="nav-menu list-unstyled d-flex flex-md-row align-items-md-center">
<!-- Notifications dropdown-->
<li class="nav-item dropdown"> <a id="notifications" rel="nofollow" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link"><i class="fa fa-bell"></i><span class="badge badge-warning">12</span></a>
<ul aria-labelledby="notifications" class="dropdown-menu">
<li><a rel="nofollow" href="#" class="dropdown-item">
<div class="notification d-flex justify-content-between">
<div class="notification-content"><i class="fa fa-envelope"></i>You have 6 new messages </div>
<div class="notification-time"><small>4 minutes ago</small></div>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item">
<div class="notification d-flex justify-content-between">
<div class="notification-content"><i class="fa fa-twitter"></i>You have 2 followers</div>
<div class="notification-time"><small>4 minutes ago</small></div>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item">
<div class="notification d-flex justify-content-between">
<div class="notification-content"><i class="fa fa-upload"></i>Server Rebooted</div>
<div class="notification-time"><small>4 minutes ago</small></div>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item">
<div class="notification d-flex justify-content-between">
<div class="notification-content"><i class="fa fa-twitter"></i>You have 2 followers</div>
<div class="notification-time"><small>10 minutes ago</small></div>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item all-notifications text-center"> <strong> <i class="fa fa-bell"></i>view all notifications </strong></a></li>
</ul>
</li>
<!-- Messages dropdown-->
<li class="nav-item dropdown"> <a id="messages" rel="nofollow" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link"><i class="fa fa-envelope"></i><span class="badge badge-info">10</span></a>
<ul aria-labelledby="notifications" class="dropdown-menu">
<li><a rel="nofollow" href="#" class="dropdown-item d-flex">
<div class="msg-profile"> <img src="../static/jquerybootstraphtmoban/img/avatar-1.jpg" alt="..." class="img-fluid rounded-circle"></div>
<div class="msg-body">
<h3 class="h5">Jason Doe</h3><span>sent you a direct message</span><small>3 days ago at 7:58 pm - 10.06.2019</small>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item d-flex">
<div class="msg-profile"> <img src="../static/jquerybootstraphtmoban/img/avatar-2.jpg" alt="..." class="img-fluid rounded-circle"></div>
<div class="msg-body">
<h3 class="h5">Frank Williams</h3><span>sent you a direct message</span><small>3 days ago at 7:58 pm - 10.06.2019</small>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item d-flex">
<div class="msg-profile"> <img src="../static/jquerybootstraphtmoban/img/avatar-3.jpg" alt="..." class="img-fluid rounded-circle"></div>
<div class="msg-body">
<h3 class="h5">Ashley Wood</h3><span>sent you a direct message</span><small>3 days ago at 7:58 pm - 10.06.2019</small>
</div></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item all-notifications text-center"> <strong> <i class="fa fa-envelope"></i>Read all messages </strong></a></li>
</ul>
</li>
<!-- Languages dropdown -->
<li class="nav-item dropdown"><a id="languages" rel="nofollow" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link language dropdown-toggle"><img src="../static/jquerybootstraphtmoban/img/flags/16/GB.png" alt="English"><span class="d-none d-sm-inline-block">English</span></a>
<ul aria-labelledby="languages" class="dropdown-menu">
<li><a rel="nofollow" href="#" class="dropdown-item"> <img src="{% static 'jquerybootstraphtmoban/img/flags/16/DE.png' %}" alt="English" class="mr-2"><span>German</span></a></li>
<li><a rel="nofollow" href="#" class="dropdown-item"> <img src="{% static 'jquerybootstraphtmoban/img/flags/16/FR.png' %}" alt="English" class="mr-2"><span>French </span></a></li>
</ul>
</li>
<span style="color: white">{{ request.user.username }}</span>
<!-- Log out-->
<li class="nav-item"><a href="{% url 'logout' %}" class="nav-link logout"> <span class="d-none d-sm-inline-block">Logout</span><i class="fa fa-sign-out"></i></a></li>
</ul>
</div>
</div>
</nav>
</header>
<!-- Updates Section -->
{% block content %}
{% endblock %}
<footer class="main-footer">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<p>Copyright © 2019.Company name All rights reserved.</p>
</div>
</div>
</div>
</footer>
</div>
<!-- JavaScript files-->
<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="{% static 'jquerybootstraphtmoban/vendor/popper.js/umd/popper.min.js' %}"> </script>
<script src="https://www.jq22.com/jquery/bootstrap-4.2.1.js"></script>
<script src="{% static 'jquerybootstraphtmoban/js/grasp_mobile_progress_circle-1.0.0.min.js' %}"></script>
<script src="{% static 'jquerybootstraphtmoban/vendor/jquery.cookie/jquery.cookie.js' %}"> </script>
<script src="{% static 'jquerybootstraphtmoban/vendor/chart.js/Chart.min.js' %}"></script>
<script src="{% static 'jquerybootstraphtmoban/vendor/jquery-validation/jquery.validate.min.js' %}"></script>
<script src="{% static 'jquerybootstraphtmoban/vendor/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js' %}"></script>
<script src="{% static 'jquerybootstraphtmoban/js/charts-home.js' %}"></script>
<!-- Main File-->
<script src="{% static 'jquerybootstraphtmoban/js/front.js' %}"></script>
{% block jsac %}
{% endblock %}
</body>
</html>
index.html
{% extends 'base.html' %}
{% block content %}
{% block css %}
<style>
.upload{
position: relative;
overflow: hidden;
width: 200px;
}
.card-body .upload #uploadFile{
opacity: 0;
position: absolute;
top: 0;
bottom: 1px;
width: auto;
left: -2px;
overflow: hidden;
}
.file-btn{
position: absolute;
width: 90px;
}
</style>
{% endblock %}
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>学生管理</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-0"><p class="col-md-2"><a href="{% url 'add' %}"><buttom class="btn btn-success">添加</buttom></a></p></div>
<!--批量导入-->
<div>
<form action="{% url 'stu_excel' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="btn btn-default upload form-control">
<div class="glyphicon glyphicon-level-up">批量上传</div>
<input type="file" multiple name="uploadFile" id="uploadFile">
</div>
<input type="submit" class="file-btn btn-info btn" value="批量导入">
</form>
</div>
<!--搜索框-->
<div class="col-md-4 col-md-offset-4">
<form action="{% url 'search' %} "method="post">
{% csrf_token %}
<input type="text" class="form-control col-md-4" name="key_word" value="{{ key_word }}">
<select name="cate" id="" class="form-control col-md-2">
<option value="name">姓名</option>
<option value="clas">班级</option>
</select>
<input type="submit" class=" btn-success btn">
</form>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>生日</th>
<th>班级</th>
<th>选修课程</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for stu in stu_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ stu.name }}</td>
<td>{{ stu.age }}</td>
<td>{{ stu.get_sex_display }}</td>
<td>{{ stu.birthday| date:'Y-d-m' }}</td>
<td>{{ stu.clas.name }}</td>
<td>
{% for cour in stu.courses.all %}
<buttom class="btn btn-info">{{ cour.title }}</buttom>
{% endfor %}
</td>
<td>
<a href="{% url 'edit' stu.id %}" class="btn btn-success">编辑</a>
<a href="{% url 'delete' stu.id %}" class="btn btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!--分页-->
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="/student?page=1" aria-label="Previous"> <!--首页=当前页面page=1-->
<span aria-hidden="true">首页</span>
</a>
{% if stu_list.has_previous %} <!--判断是否有上一页-->
<!--如果有上一页,就通过链接请求上一页-->
<a href="/student?page={{ stu_list.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true"><</span>
</a>
{% endif %}
</li>
<!--中间的页码数字-->
{% for page_num in page_range %} <!--循环整个页码数列表-->
{% if page_num == visit_page_num %} <!--判断循环的页数是否等于当前访问的页数,如果是就加 active-->
<li class="active"><a href="/student?page={{ page_num }}">{{ page_num }}</a></li>
{% else %}
<li><a href="/student?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
<li>
{% if stu_list.has_next %} <!--判断是否有下一页-->
<!--如果有下一页,就通过链接请求下一页-->
<a href="/student?page={{ stu_list.next_page_number }}" aria-label="Next">
<span aria-hidden="true"> > </span>
</a>
{% endif %}
<a href="/student?page={{ paginator.num_pages }}" aria-label="Next">
<span aria-hidden="true">尾页</span>
</a>
</li>
</ul>
</nav>
{% endblock %}
stu_add_edit.html
{% extends 'base.html' %}
{% block content %}
<div class="col-lg-12">
<div class="card">
<div class="card-header d-flex align-items-center">
{% if stu_id %}
<h4>编辑学生</h4>
{% else %}
<h4>添加学生</h4>
{% endif %}
</div>
<div class="card-body">
{% if stu_id %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label>姓名</label>
<input type="text" placeholder="姓名" class="form-control"name="name" value="{{ stu.name }}">
</div>
<div class="form-group">
<label>年龄</label>
<input type="text" placeholder="年龄" class="form-control" name="age" value="{{ stu.age }}">
</div>
<div class="form-group">
<label>性别</label>
<select name="sex" id="sex" class="form-control">
<option value="1">男</option>
<option value="0">女</option>
<option value="2">保密</option>
</select>
</div>
<div class="form-group">
<label>生日</label>
<input type="date" placeholder="Password" class="form-control" name="birthday" value="{{ stu.birthday|date:'Y-m-d' }}">
</div>
<div class="form-group">
<label>班级</label>
<select name="clas_id" id="" class="form-control">
{% for i in clas %}
{% if i.id == stu.clas_id %}
<option selected value="{{ i.id }}">{{ i.name }}</option>
{% endif %}
<option value="{{ i.id }}">{{ i.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label>选修课程</label>
<select name="course" id="clas_id" multiple class="form-control">
{% for cla in course %}
{% if cla in stu.courses.all %}
<option selected value="{{ cla.id }}">{{ cla.title }}</option>
{% else %}
<option value="{{ cla.id }}">{{ cla.title }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="form-group">
<input type="submit" value="Signin" class="btn btn-primary">
</div>
</form>
{% else %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label>姓名</label>
<input type="text" placeholder="姓名" class="form-control"name="name">
</div>
<div class="form-group">
<label>年龄</label>
<input type="text" placeholder="年龄" class="form-control" name="age">
</div>
<div class="form-group">
<label>性别</label>
<select name="sex" id="" class="form-control">
<option value="1">男</option>
<option value="0">女</option>
<option value="2">保密</option>
</select>
</div>
<div class="form-group">
<label>生日</label>
<input type="date" placeholder="Password" class="form-control" name="birthday">
</div>
<div class="form-group">
<label>班级</label>
<select name="clas_id" id="" class="form-control">
{% for i in clas %}
<option value="{{ i.id }}">{{ i.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label>选修课程</label>
<select name="course" id="" multiple class="form-control">
{% for cour in course %}
<option value="{{ cour.id }}">{{ cour.title }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<input type="submit" value="Signin" class="btn btn-primary">
</div>
</form>
{% endif %}
</div>
</div>
</div>
{% block jsac %}
<script>
$(function(){
$(" .card-body #sex option").each(function() {
var num = parseInt($(this).val());
if(parseInt(num) == {{ stu.sex }}) {
$(this).attr("selected",'selected');
}
})
}) ;
</script>
{% endblock %}
{% endblock %}
course.html
{% extends 'base.html' %}
{% block content %}
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h4>课程管理</h4>
</div>
<div class="card-body">
<div class="row"><p class="col-md-2"><a href="{% url 'course_add' %}"><buttom class="btn btn-success">添加</buttom></a></p></div>
<div class="table-responsive">
<form action="" method="post">
<p>
<table class="table table-striped table-hover">
<thead>
<tr>
<th><input type="checkbox" class="all_course" name="all_course" > 选择</th>
<th>序号</th>
<th>课程名称</th>
<th>讲师</th>
<th>学分</th>
<th>上课时间</th>
<th>上课教室</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for cour in course %}
<tr>
<td><input type="checkbox" name="course_list" value="{{ cour.id }}"></td>
<td>{{ forloop.counter }}</td>
<td>{{ cour.title }}</td>
<td>{{ cour.teacher|default:'暂无' }}</td>
<td>{{ cour.credit }}</td>
<td>{{ cour.classTime|default:'暂无' }}</td>
<td>{{ cour.classAddr|default:'暂无' }}</td>
<td>
<a href="{% url 'course_edit' cour.id %}" class="btn btn-success">编辑</a>
<a href="{% url 'course_delete' cour.id %}" class="btn btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<input type="submit" class="btn btn-info pull-right">
</form>
</div>
</div>
</div>
</div>
<!--分页-->
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="/course?page=1" aria-label="Previous"> <!--首页=当前页面page=1-->
<span aria-hidden="true">首页</span>
</a>
{% if course.has_previous %} <!--判断是否有上一页-->
<!--如果有上一页,就通过链接请求上一页-->
<a href="/course?page={{ course.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true"><</span>
</a>
{% endif %}
</li>
<!--中间的页码数字-->
{% for page_num in page_range %} <!--循环整个页码数列表-->
{% if page_num == visit_page_num %} <!--判断循环的页数是否等于当前访问的页数,如果是就加 active-->
<li class="active"><a href="/course?page={{ page_num }}">{{ page_num }}</a></li>
{% else %}
<li><a href="/course?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
<li>
{% if course.has_next %} <!--判断是否有下一页-->
<!--如果有下一页,就通过链接请求下一页-->
<a href="/course?page={{ course.next_page_number }}" aria-label="Next">
<span aria-hidden="true"> > </span>
</a>
{% endif %}
<a href="/course?page={{ paginator.num_pages }}" aria-label="Next">
<span aria-hidden="true">尾页</span>
</a>
</li>
</ul>
</nav>
{% block jsac %}
<script>
$('.all_course').click(function () {
$('input:checkbox').attr("checked", '');
})
</script>
{% endblock %}
{% endblock %}
course_add_edit.html
{% extends 'base.html' %}
{% block content %}
<div class="col-lg-12">
<div class="card">
<div class="card-header d-flex align-items-center">
{% if course_id %}
<h4>编辑课程</h4>
{% else %}
<h4>添加课程</h4>
{% endif %}
</div>
<div class="card-body">
{% if course_id %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label>课程名称</label>
<input type="text" placeholder="课程名称" class="form-control" name="title" value="{{ cour.title }}">
</div>
<div class="form-group">
<label>讲师</label>
<input type="text" placeholder="讲师" class="form-control" name="teacher" value="{{ cour.teacher }}">
</div>
<div class="form-group">
<label>学分</label>
<input type="text" placeholder="学分" class="form-control" name="credit" value="{{ cour.credit }}">
</div>
<div class="form-group">
<label>上课时间</label>
<input type="text" placeholder="上课时间" class="form-control" name="classTime" value="{{ cour.classTime }}">
</div>
<div class="form-group">
<label>上课教室</label>
<input type="text" placeholder="上课教室" class="form-control" name="classAddr" value="{{ cour.classAddr }}">
</div>
<div class="form-group">
<input type="submit" value="Signin" class="btn btn-primary">
</div>
</form>
{% else %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label>课程名称</label>
<input type="text" placeholder="课程名称" class="form-control" name="title">
</div>
<div class="form-group">
<label>讲师</label>
<input type="text" placeholder="讲师" class="form-control" name="teacher">
</div>
<div class="form-group">
<label>学分</label>
<input type="text" placeholder="学分" class="form-control" name="credit">
</div>
<div class="form-group">
<label>上课时间</label>
<input type="text" placeholder="上课时间" class="form-control" name="classTime">
</div>
<div class="form-group">
<label>上课教室</label>
<input type="text" placeholder="上课教室" class="form-control" name="classAddr">
</div>
<div class="form-group">
<input type="submit" value="Signin" class="btn btn-primary">
</div>
</form>
{% endif %}
</div>
</div>
</div>
{% endblock %}
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Bootstrap Dashboard</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="all,follow">
<!-- Bootstrap CSS-->
<link rel="stylesheet" href="https://www.jq22.com/jquery/bootstrap-4.2.1.css">
<!-- Font Awesome CSS-->
<link rel="stylesheet" href="https://www.jq22.com/jquery/font-awesome.4.7.0.css">
<!-- Fontastic Custom icon font-->
<link rel="stylesheet" href="../static/jquerybootstraphtmoban/css/fontastic.css">
<!-- Google fonts - Roboto -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<!-- jQuery Circle-->
<link rel="stylesheet" href="../static/jquerybootstraphtmoban/css/grasp_mobile_progress_circle-1.0.0.min.css">
<!-- Custom Scrollbar-->
<link rel="stylesheet" href="../static/jquerybootstraphtmoban/vendor/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css">
<!-- theme stylesheet-->
<link rel="stylesheet" href="../static/jquerybootstraphtmoban/css/style.default.css" id="theme-stylesheet">
<!-- Custom stylesheet - for your changes-->
<link rel="stylesheet" href="../static/jquerybootstraphtmoban/css/custom.css">
<!-- Favicon-->
<link rel="shortcut icon" href="../static/jquerybootstraphtmoban/img/favicon.ico">
<!-- Tweaks for older IEs--><!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<div class="page login-page">
<div class="container">
<div class="form-outer text-center d-flex align-items-center">
<div class="form-inner">
<div class="logo text-uppercase"><span>Bootstrap</span><strong class="text-primary">Dashboard</strong></div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud.</p>
<form method="post" class="text-left form-validate">
{% csrf_token %}
<div class="form-group-material">
<input id="login-username" type="text" name="loginUsername" required data-msg="Please enter your username" class="input-material">
<label for="login-username" class="label-material">Username</label>
</div>
<div class="form-group-material">
<input id="login-password" type="password" name="loginPassword" required data-msg="Please enter your password" class="input-material">
<label for="login-password" class="label-material">Password</label>
</div>
<div class="form-group text-center">
<input type="submit" value="Login" class="btn btn-primary">
<!-- This should be submit button but I replaced it with <a> for demo purposes-->
</div>
</form><a href="#" class="forgot-pass">Forgot Password?</a><small>Do not have an account? </small><a href="register.html" class="signup">Signup</a>
</div>
<div class="copyrights text-center">
</div>
</div>
</div>
</div>
<!-- JavaScript files-->
<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="../static/jquerybootstraphtmoban/vendor/popper.js/umd/popper.min.js"> </script>
<script src="https://www.jq22.com/jquery/bootstrap-4.2.1.js"></script>
<script src="../static/jquerybootstraphtmoban/js/grasp_mobile_progress_circle-1.0.0.min.js"></script>
<script src="../static/jquerybootstraphtmoban/vendor/jquery.cookie/jquery.cookie.js"> </script>
<script src="../static/jquerybootstraphtmoban/vendor/chart.js/Chart.min.js"></script>
<script src="../static/jquerybootstraphtmoban/vendor/jquery-validation/jquery.validate.min.js"></script>
<script src="../static/jquerybootstraphtmoban/vendor/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js"></script>
<!-- Main File-->
<script src="../static/jquerybootstraphtmoban/js/front.js"></script>
</body>
</html>
页面展示
jq模板连接:https://www.jq22.com/jquery-info22857
登录

学生管理

课程管理


浙公网安备 33010602011771号