背景:创建一个简单的学生管理系统,熟悉增删改查操作

一:创建一个Django项目(http://www.cnblogs.com/wupeiqi/articles/6216618.html)

1:创建实体类

from django.db import models

# Create your models here.
class Classes(models.Model):
# 班级表
title=models.CharField(max_length=32)
# 班级-教师:多对多
m=models.ManyToManyField("Teachers") class Teachers(models.Model):
# 教师表
name = models.CharField(max_length=32) class Students(models.Model):
# 学生表
name=models.CharField(max_length=32)
age=models.IntegerField()
gender=models.NullBooleanField()
# 学生-班级 多对一
cs=models.ForeignKey(Classes)

实体类

2:同步到数据库

python manage.py makemigrations

python manage.py migrate

3:考虑到页面逻辑比较多,所以将原来的View.py文件删掉,新增一个View文件夹,把每个页面的业务逻辑创建对应文件(classes.py+students.py+teachers.py)

二:班级表的增删改查(单表操作)

1:展示班级信息列表

  a:配置路由   

"""StudentManageSystem URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from App01.Views import classes
from django.conf.urls import url
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^get_classes.html$',classes.get_classes),
url(r'^add_classes.html$',classes.add_classes),
url(r'^del_classes.html$', classes.del_classes),
url(r'^edit_classes.html$', classes.edit_classes) ]

配置路由

  b:view中控制逻辑

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from App01 import models
def get_classes(request):
cls_list=models.Classes.objects.all()
return render(request,"get_classes.html",{'cls_list':cls_list}) def add_classes(request):
if request.method=='GET':
#如果是通过get请求进来表示只是展示页面
return render(request, "add_classes.html")
elif request.method=='POST':
title=request.POST.get("title")
models.Classes.objects.create(title=title)
return redirect("get_classes.html")
def del_classes(request):
if request.method=='GET':
nid = request.GET.get("nid")
models.Classes.objects.filter(id=nid).delete()
return redirect("get_classes.html")
def edit_classes(request):
if request.method=='GET':
#如果是通过get请求进来表示只是展示页面,注意需要将title值显示到文本框中
nid = request.GET.get("nid")
classesEntity=models.Classes.objects.filter(id=nid).first()
return render(request, "edit_classes.html",{'classesEntity':classesEntity})
elif request.method=='POST':
nid = request.GET.get("nid")
title=request.POST.get("title")
models.Classes.objects.filter(id=nid).update(title=title)
return redirect("get_classes.html")

classes.py

  c:html页面模板设置

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<a href="add_classes.html">添加</a>
</div>
<div>
<table border="">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in cls_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.title }}</td>
<td>
<a href="/del_classes.html?nid={{row.id}}">删除</a>
|
<a href="/edit_classes.html?nid={{row.id}}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>

get_classes.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form method="post" action="add_classes.html">
{% csrf_token %}
<input type="text" name="title">
<input type="submit" value="提交">
</form>
</body>
</html>

add_classes.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form method="post" action="add_classes.html">
{% csrf_token %}
<input type="text" name="title">
<input type="submit" value="提交">
</form>
</body>
</html>

edit_classes.html

2:运行效果

三:学生表的增删改查(外键操作)

1:展示学生信息列表

  a:配置路由   

"""StudentManageSystem URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from App01.Views import classes,students
from django.conf.urls import url
urlpatterns = [
url('admin/', admin.site.urls),
# 班级管理 路由
url(r'^get_classes.html$',classes.get_classes),
url(r'^add_classes.html$',classes.add_classes),
url(r'^del_classes.html$', classes.del_classes),
url(r'^edit_classes.html$', classes.edit_classes),
# 学生管理 路由
url(r'^get_students.html$', students.get_students),
url(r'^add_students.html$', students.add_students),
url(r'^del_students.html$', students.del_students),
url(r'^edit_students.html$', students.edit_students) ]

url

  b:view中控制逻辑

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from App01 import models
def get_students(request):
stu_list=models.Students.objects.all()
return render(request,"get_students.html",{'stu_list':stu_list}) def add_students(request):
if request.method=='GET':
#如果是通过get请求进来表示只是展示页面
cs_list = models.Classes.objects.all()
return render(request, "add_students.html",{'cs_list':cs_list})
elif request.method=='POST':
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cs')
models.Students.objects.create(
name=name,
age=age,
gender=gender,
cs_id=cs
)
return redirect("get_students.html")
def del_students(request):
if request.method=='GET':
nid = request.GET.get("nid")
models.Students.objects.filter(id=nid).delete()
return redirect("get_students.html")
def edit_students(request):
if request.method=='GET':
#如果是通过get请求进来表示只是展示页面,注意需要将title值显示到文本框中
nid = request.GET.get("nid")
obj=models.Students.objects.filter(id=nid).first()
cs_list = models.Classes.objects.all()
return render(request, "edit_students.html",{'obj':obj,'cs_list':cs_list})
elif request.method=='POST':
nid = request.GET.get("nid")
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cs')
models.Students.objects.filter(id=nid).update(name=name,age=age,gender=gender,cs_id=cs)
return redirect("get_students.html")

Students.py

  c:html页面模板设置

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<a href="add_students.html">添加</a>
</div>
<div>
<table border="">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in stu_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.age }}</td>
{% if row.gender %}
<td>男</td>
{% else %}
<td>女</td>
{% endif %}
<td>{{ row.cs.title }}</td>
<td>
<a href="/del_students.html?nid={{row.id}}">删除</a>
|
<a href="/edit_students.html?nid={{row.id}}">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>

get_students.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form method="post" action="add_students.html">
{% csrf_token %}
<p><input type="text" name="name" placeholder="请输入姓名"></p>
<p><input type="text" name="age" placeholder="请输入年龄"></p>
<p>
<input type="radio" name="gender" value="">男
<input type="radio" name="gender" value="">女
</p>
<p>
<select name="cs">
{% for row in cs_list %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endfor %}
</select>
</p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>

add_students.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="edit_students.html?nid={{ obj.id }}" method="POST">
{% csrf_token %}
{# <p style="display: none"> <input type="text" name="id" value="{{ obj.id }}" /></p>#}
<p> <input type="text" name="name" value="{{ obj.name }}" /></p>
<p> <input type="text" name="age" value="{{ obj.age }}" /></p>
<p>
{% if obj.gender %}
男:<input type="radio" name="gender" checked="checked" value="" />
女:<input type="radio" name="gender" value="" />
{% else %}
男:<input type="radio" name="gender" value="" />
女:<input type="radio" name="gender" value="" checked="checked" />
{% endif %}
</p>
<p>
<select name="cs">
{% for row in cs_list %}
{% if row.id == obj.cs_id %}
<option value="{{ row.id }}" selected="selected" >{{ row.title }}</option>
{% else %}
<option value="{{ row.id }}">{{ row.title }}</option>
{% endif %}
{% endfor %}
</select>
</p>
<input type="submit" value="提交" />
</form>
</body>
</html>

edit_students.html

2:运行效果

四、为班级分配教师

  a:配置路由   

url(r'^set_teachers.html$', classes.set_teachers),

  b:view中控制逻辑

def set_teachers(request):
if request.method=='GET':
#如果是通过get请求进来表示只是展示页面,注意需要将班级已有的教师选中
nid = request.GET.get("nid")
# 获取当前班级
classesEntity = models.Classes.objects.filter(id=nid).first()
#获取所有的教师
teachersList = models.Teachers.objects.all()
# 获取当前班级已分配的教师
selectTeacherList=classesEntity.m.all()
return render(request, "set_teachers.html",{'classesEntity':classesEntity,'teachersList':teachersList,'selectTeacherList':selectTeacherList})
elif request.method=='POST':
nid = request.GET.get("nid")
# 注意,这里是设置getlist()
selectTeacherIds=request.POST.getlist("selectTeacherIds")
print()
print(selectTeacherIds)
models.Classes.objects.filter(id=nid).first().m.set(selectTeacherIds)
return redirect("get_classes.html")

在classesview中添加方法

   c:html页面模板设置

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form method="post" action="set_teachers.html?nid={{ classesEntity.id }}">
{% csrf_token %}
<select multiple="multiple" size="" name="selectTeacherIds">
{% for teacher in teachersList %}
{% if teacher in selectTeacherList %}
<option value="{{ teacher.id }}" selected="selected">{{ teacher.name }}</option>
{% else %}
<option value="{{ teacher.id }}">{{ teacher.name }}</option>
{% endif %}
{% endfor %}
</select>
<input type="submit" value="提交">
</form>
</body>
</html>

set_teachers.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<a href="add_classes.html">添加</a>
</div>
<div>
<table border="">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>任课老师</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in cls_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.title }}</td>
<td>
{% for item in row.m.all %}
<span>{{ item.name }}</span>
{% endfor %}
</td>
<td>
<a href="/del_classes.html?nid={{row.id}}">删除</a>
|
<a href="/edit_classes.html?nid={{row.id}}">编辑</a>
|
<a href="/set_teachers.html?nid={{row.id}}">分配教师</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>

get_classes.html

学生管理系统2.0版本

接下啦我们使用一些常用的组件,对系统的页面和功能进行优化

五:页面优化

配置static文件夹,用于存放一些外部的引用(js、css等其他插件)

1:下载和使用bootstrap插件

2:如果Bootstrap中的icon的内容不符合我们的要求我们还可以使用Font Awesome图标字体库,(我这里就不用了)

3:修改setting中的MIDDLEWARE的csrf

"""
Django settings for StudentManageSystem project. Generated by 'django-admin startproject' using Django 2.1.5. For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '&6e&089_g+(58rk7&jh^)ewqe3_-xujk%0u(ukgi&6_jj28r)@' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'App01.apps.App01Config',
] 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',
] ROOT_URLCONF = 'StudentManageSystem.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'StudentManageSystem.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
} # Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/'
STATICFILES_DIRS=(
os.path.join(BASE_DIR,'static'),
)

settings.py

4:配置url学生管理2.0 路由

"""StudentManageSystem URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from App01.Views import classes,students
from django.conf.urls import url
urlpatterns = [
url('admin/', admin.site.urls),
# 班级管理 路由
url(r'^get_classes.html$',classes.get_classes),
url(r'^add_classes.html$',classes.add_classes),
url(r'^del_classes.html$', classes.del_classes),
url(r'^edit_classes.html$', classes.edit_classes),
# 为班级分配老师
url(r'^set_teachers.html$', classes.set_teachers),
# 学生管理 路由
url(r'^get_students.html$', students.get_students),
url(r'^add_students.html$', students.add_students),
url(r'^del_students.html$', students.del_students),
url(r'^edit_students.html$', students.edit_students),
# 学生管理2.0 路由
url(r'^addStudent$', students.addStudent),
]

urls.py

5:学生页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{#引入css和Bootstrap#}
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/plugins/fontawesome/css/fontawesome.css">
</head>
<body>
<div class="container">
<a class="btn btn-primary" id="addBtn">添加</a>
<a class="btn btn-danger" id="delBtn">删除</a>
<table class="table table-hover table-bordered">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in stu_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.age }}</td>
{% if row.gender %}
<td>男</td>
{% else %}
<td>女</td>
{% endif %}
<td>{{ row.cs.title }}</td>
<td>
<a class="glyphicon glyphicon-remove"></a> <i class="glyphicon glyphicon-pencil"></i> </td>
</tr>
{% endfor %}
</tbody>
</table>
</div> <!-- Modal -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel">学生信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="formStudentInfo">
<div class="form-group">
<label for="userName" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="userName" name="userName" placeholder="请输入姓名">
</div>
</div>
<div class="form-group">
<label for="age" class="col-sm-2 control-label">年龄</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="age" name="age" placeholder="年龄">
</div>
</div> <div class="form-group">
<label for="gender" class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" value=""> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" value=""> 女
</label>
</div>
</div>
<div class="form-group">
<label for="classes" class="col-sm-2 control-label">班级</label>
<div class="col-sm-10">
<select class="form-control" id="cls_ids" name="cls_ids">
{% for item in cs_list %}
<option value="{{ item.id }}">{{ item.title }}</option>
{% endfor %}
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<span id="errorMsg" style="color: red"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
{#引入jQuery和Bootstrap#}
<script src="/static/js/jquery-3.3.1.min.js"></script>
<script src="/static/plugins/bootstrap/js/bootstrap.js"></script>
<script>
$(function () {
bindEvent();
bindSave();
})
{#给添加按钮绑定,弹出模态窗口的事件#} function bindEvent() {
$("#addBtn").click(function () {
$("#addModal").modal('show');
})
} {#给保存按钮绑定调用后台事件#} function bindSave() { $("#btnSave").click(function () {
var datas = {}
{#遍历页面上所有的控件#}
$("#formStudentInfo").find("input,select").each(function () {
debugger;
var v = $(this).val();
var n = $(this).attr('name');
if (n == "gender") {
if ($(this).prop("checked")) {
datas[n] = v;
}
} else {
datas[n] = v;
}
}); $.ajax({
url: "addStudent",
type: 'POST',
data: datas,
success: function (arg) {
{# 将返回的信息,转化成数据#}
var mess=JSON.parse(arg);
if(mess.status){
{#添加成功,刷新页面#}
window.location.reload()
}else{
$("#errorMsg").text(mess.message)
}
}
})
}) }
</script> </body>
</html>

get_students.html

6:后台处理页面

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from App01 import models
import json def get_students(request):
stu_list = models.Students.objects.all()
cs_list = models.Classes.objects.all()
return render(request, "get_students.html", {'stu_list': stu_list, 'cs_list': cs_list}) def add_students(request):
if request.method == 'GET':
# 如果是通过get请求进来表示只是展示页面
cs_list = models.Classes.objects.all()
return render(request, "add_students.html", {'cs_list': cs_list})
elif request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cs')
models.Students.objects.create(
name=name,
age=age,
gender=gender,
cs_id=cs
)
return redirect("get_students.html") def del_students(request):
if request.method == 'GET':
nid = request.GET.get("nid")
models.Students.objects.filter(id=nid).delete()
return redirect("get_students.html") def edit_students(request):
if request.method == 'GET':
# 如果是通过get请求进来表示只是展示页面,注意需要将title值显示到文本框中
nid = request.GET.get("nid")
obj = models.Students.objects.filter(id=nid).first()
cs_list = models.Classes.objects.all()
return render(request, "edit_students.html", {'obj': obj, 'cs_list': cs_list})
elif request.method == 'POST':
nid = request.GET.get("nid")
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cs')
models.Students.objects.filter(id=nid).update(name=name, age=age, gender=gender, cs_id=cs)
return redirect("get_students.html") def addStudent(request):
response = {"status":True,"message":None}
name = request.POST.get('userName')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cls_ids') try:
print(name,age,gender,cs)
models.Students.objects.create(
name=name,
age=age,
gender=gender,
cs_id=cs
)
except:
response["status"]=False
response["message"]="输入的格式不正确"
# 把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)
return HttpResponse(result)

addStudent

7:显示效果

8:修改HTML页面中的js,使得数据添加成功后,不刷新页面

主要实现原理是:ajax回调成功后,拼接一个tr,添加到原来的table中

9:删除功能以及删除bug修改

    # 学生管理2.0  路由
url(r'^addStudent$', students.addStudent),
url(r'^delStudent$', students.delStudent),

url路由设置

def addStudent(request):
response = {"status":True,"message":None,"obj":None}
name = request.POST.get('userName')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cls_ids') try:
print(name,age,gender,cs)
obj=models.Students.objects.create(
name=name,
age=age,
gender=gender,
cs_id=cs
)
response["obj"] = obj.id
print(response)
except:
response["status"]=False
response["message"]="输入的格式不正确"
# 把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)
return HttpResponse(result) def delStudent(request):
response = {"status": True, "message": None, "obj": None}
try:
nid = request.GET.get("rowID")
models.Students.objects.filter(id=nid).delete()
except:
response["status"] = False
response["message"] = "删除失败"
# 把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)
return HttpResponse(result)

逻辑层,逻辑控制

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{#引入css和Bootstrap#}
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/plugins/fontawesome/css/fontawesome.css">
</head>
<body>
<div class="container">
<a class="btn btn-primary" id="addBtn">添加</a>
<a class="btn btn-danger" id="delBtn">删除</a>
<table id="tbStudentsList" class="table table-hover table-bordered">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in stu_list %}
<tr nid="{{ row.id }}">
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.age }}</td>
{% if row.gender %}
<td>男</td>
{% else %}
<td>女</td>
{% endif %}
<td>{{ row.cs.title }}</td>
<td>
<a class="glyphicon glyphicon-remove del-row"></a> <i class="glyphicon glyphicon-pencil"></i> </td>
</tr>
{% endfor %}
</tbody>
</table>
</div> <!-- 添加模态窗口 -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel">学生信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="formStudentInfo">
<div class="form-group">
<label for="userName" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="userName" name="userName" placeholder="请输入姓名">
</div>
</div>
<div class="form-group">
<label for="age" class="col-sm-2 control-label">年龄</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="age" name="age" placeholder="年龄">
</div>
</div> <div class="form-group">
<label for="gender" class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" value=""> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" value=""> 女
</label>
</div>
</div>
<div class="form-group">
<label for="classes" class="col-sm-2 control-label">班级</label>
<div class="col-sm-10">
<select class="form-control" id="cls_ids" name="cls_ids">
{% for item in cs_list %}
<option value="{{ item.id }}">{{ item.title }}</option>
{% endfor %}
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<span id="errorMsg" style="color: red"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
<!-- 删除模态窗口 -->
<div class="modal fade" id="delModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="alert alert-danger" role="alert">
<h3>删除学生信息?</h3>
<div>...<input style="display: none;" type="text" id="delNid"/></div>
<div>
<button id="cancelConfirm" type="button" class="btn btn-default">取消</button>
<button id="delConfirm" type="button" class="btn btn-danger">确定</button>
</div> </div>
</div>
</div>
{#引入jQuery和Bootstrap#}
<script src="/static/js/jquery-3.3.1.min.js"></script>
<script src="/static/plugins/bootstrap/js/bootstrap.js"></script>
<script>
$(function () {
bindEvent();
bindSave();
bindDel(); })
{#给添加按钮绑定,弹出模态窗口的事件#} function bindEvent() {
$("#addBtn").click(function () {
$("#addModal").modal('show');
})
} {#给保存按钮绑定调用后台事件#} function bindSave() {
$("#btnSave").click(function () {
var datas = {}
{#遍历页面上所有的控件#}
$("#formStudentInfo").find("input,select").each(function () {
var v = $(this).val();
var n = $(this).attr('name');
if (n == "gender") {
if ($(this).prop("checked")) {
datas[n] = v;
}
} else {
datas[n] = v;
}
{#添加一个班级名称,方便后面不刷新页面直接显示的时候使用#}
if (n == "cls_ids") {
datas["classesName"] = $("#cls_ids option:selected").text();
}
}); $.ajax({
url: "addStudent",
type: 'POST',
data: datas,
success: function (arg) {
{# 将返回的信息,转化成数据#}
var mess = JSON.parse(arg);
if (mess.status) {
{#添加成功,刷新页面#}
{#window.location.reload()#}
{#添加成功,不刷新页面#}
createNewRecord(datas, mess.obj)
$("#addModal").modal('hide');
} else {
$("#errorMsg").text(mess.message)
}
}
})
}) } function createNewRecord(data, obj) {
var tr = document.createElement('tr');
{#id#}
var tid = '<td>' + obj + '</td>';
$(tr).append(tid);
{#姓名#}
var tName = '<td>' + data.userName + '</td>';
$(tr).append(tName);
{#年龄#}
var tage = '<td>' + data.age + '</td>';
$(tr).append(tage);
{#性别#}
var tdGender = document.createElement('td');
if (data.gender == "") {
tdGender.innerHTML = '女';
} else {
tdGender.innerHTML = '男';
}
$(tr).append(tdGender);
{#班级#}
var tdclassName = '<td>' + data.classesName + '</td>';
$(tr).append(tdclassName);
var tdHandle = '<td><a class="glyphicon glyphicon-remove"></a><i class="glyphicon glyphicon-pencil"></i></td>';
$(tr).append(tdHandle);
$('#tbStudentsList').append(tr);
} {#给删除按钮绑定,弹出模态窗口的事件#} function bindDel() {
{#点击每一行的删除链接#}
$(".del-row").click(function () {
{#把删除的nid赋值给弹出窗口中的id#}
var rowId=$(this).parent().parent().attr('nid');
$("#delNid").val(rowId)
$("#delModal").modal('show');
})
{#弹出删除对话框后,取消按钮#}
$("#cancelConfirm").click(function () {
$("#delModal").modal('hide');
})
{#弹出删除确认对话框后,确定按钮#}
$("#delConfirm").click(function () {
var rowID =$("#delNid").val();
$.ajax({
url: "delStudent",
type: 'get',
data: {"rowID":rowID},
success: function (arg) {
{# 将返回的信息,转化成数据#}
var mess = JSON.parse(arg);
if (mess.status) {
{#删除成功,不刷新页面#}
$('tr[nid="'+rowID+'"]').remove();
}
$("#delModal").modal('hide');
}
}
)
}) }
</script> </body>
</html>

html

存在的bug:新增之后,再次点击删除,发现没有触发事件。

原因分析:页面没有重新加载,绑定事件没有触发。可以通过事件委托来实现

function createNewRecord(data, obj) {
var tr = document.createElement('tr');
$(tr).attr("nid",obj)
{#id#}
var tid = '<td>' + obj + '</td>';
$(tr).append(tid);
{#姓名#}
var tName = '<td>' + data.userName + '</td>';
$(tr).append(tName);
{#年龄#}
var tage = '<td>' + data.age + '</td>';
$(tr).append(tage);
{#性别#}
var tdGender = document.createElement('td');
if (data.gender == "") {
tdGender.innerHTML = '女';
} else {
tdGender.innerHTML = '男';
}
$(tr).append(tdGender);
{#班级#}
var tdclassName = '<td>' + data.classesName + '</td>';
$(tr).append(tdclassName);
var tdHandle = '<td><a class="glyphicon glyphicon-remove del-row"></a><i class="glyphicon glyphicon-pencil"></i></td>';
$(tr).append(tdHandle);
$('#tbStudentsList').append(tr);
}

html中创建tr方法

    function bindDel() {
{#点击每一行的删除链接#}
{#事件委托,解决新增的数据没有绑定删除事件的bug#}
$("#tbStudentsList").on("click",".del-row",function () {
{#把删除的nid赋值给弹出窗口中的id#}
var rowId=$(this).parent().parent().attr('nid');
$("#delNid").val(rowId)
$("#delModal").modal('show');
})
{#弹出删除对话框后,取消按钮#}
$("#cancelConfirm").click(function () {
$("#delModal").modal('hide');
})
{#弹出删除确认对话框后,确定按钮#}
$("#delConfirm").click(function () {
var rowID =$("#delNid").val();
$.ajax({
url: "delStudent",
type: 'get',
data: {"rowID":rowID},
success: function (arg) {
{# 将返回的信息,转化成数据#}
var mess = JSON.parse(arg);
if (mess.status) {
{#删除成功,不刷新页面#}
$('tr[nid="'+rowID+'"]').remove();
}
$("#delModal").modal('hide');
}
}
)
}) }

html中使用事件委托

10:编辑功能

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{#引入css和Bootstrap#}
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/plugins/fontawesome/css/fontawesome.css">
</head>
<body>
<div class="container">
<a class="btn btn-primary" id="addBtn">添加</a>
<a class="btn btn-danger" id="delBtn">删除</a>
<table id="tbStudentsList" class="table table-hover table-bordered">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in stu_list %}
<tr nid="{{ row.id }}">
<td na="entityId">{{ row.id }}</td>
<td na="entityName">{{ row.name }}</td>
<td na="entityAge">{{ row.age }}</td>
{% if row.gender %}
<td na="entityGender">男</td>
{% else %}
<td na="entityGender">女</td>
{% endif %}
<td na="entityClassName">{{ row.cs.title }}</td>
<td>
<a class="glyphicon glyphicon-remove del-row"></a> <a class="glyphicon glyphicon-pencil edit-row"></a> </td>
</tr>
{% endfor %}
</tbody>
</table>
</div> <!-- 添加模态窗口 -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel">学生信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="formStudentInfo">
<div class="form-group">
<label for="userName" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="userName" name="userName" placeholder="请输入姓名">
</div>
</div>
<div class="form-group">
<label for="age" class="col-sm-2 control-label">年龄</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="age" name="age" placeholder="年龄">
</div>
</div> <div class="form-group">
<label for="gender" class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" value=""> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" value=""> 女
</label>
</div>
</div>
<div class="form-group">
<label for="classes" class="col-sm-2 control-label">班级</label>
<div class="col-sm-10">
<select class="form-control" id="cls_ids" name="cls_ids">
{% for item in cs_list %}
<option value="{{ item.id }}">{{ item.title }}</option>
{% endfor %}
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<span id="errorMsg" style="color: red"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
<!-- 删除模态窗口 -->
<div class="modal fade" id="delModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="alert alert-danger" role="alert">
<h3>删除学生信息?</h3>
<div>...<input style="display: none;" type="text" id="delNid"/></div>
<div>
<button id="cancelConfirm" type="button" class="btn btn-default">取消</button>
<button id="delConfirm" type="button" class="btn btn-danger">确定</button>
</div> </div>
</div>
</div>
<!-- 编辑模态窗口 -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel">学生信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="formStudentInfo">
<div class="form-group" style="display: none">
<label for="id" class="col-sm-2 control-label">用户id</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="id" name="nid" na="entityId">
</div>
</div>
<div class="form-group">
<label for="userName" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="userName" name="userName" placeholder="请输入姓名"
na="entityName">
</div>
</div>
<div class="form-group">
<label for="age" class="col-sm-2 control-label">年龄</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="age" name="age" placeholder="年龄" na="entityAge">
</div>
</div>
<div class="form-group">
<label for="gender" class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" value="" na="entityGender"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" value="" na="entityGender"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="classes" class="col-sm-2 control-label">班级</label>
<div class="col-sm-10">
<select class="form-control" id="cls_ids" name="cls_ids" na="entityClassName">
{% for item in cs_list %}
<option value="{{ item.id }}">{{ item.title }}</option>
{% endfor %}
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<span id="errorMsg" style="color: red"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
{#引入jQuery和Bootstrap#}
<script src="/static/js/jquery-3.3.1.min.js"></script>
<script src="/static/plugins/bootstrap/js/bootstrap.js"></script>
<script>
$(function () {
bindEvent();
bindSave();
bindDel();
bindEdit();
})
{#给添加按钮绑定,弹出模态窗口的事件#} function bindEvent() {
$("#addBtn").click(function () {
clearEle()
$("#addModal").modal('show');
})
} {#给保存按钮绑定调用后台事件#} function bindSave() {
$("#addModal #btnSave").click(function () {
var datas = {}
{#遍历页面上所有的控件#}
$("#addModal #formStudentInfo").find("input,select").each(function () {
var v = $(this).val();
var n = $(this).attr('name');
if (n == "gender") {
if ($(this).prop("checked")) {
datas[n] = v;
}
} else {
datas[n] = v;
}
{#添加一个班级名称,方便后面不刷新页面直接显示的时候使用#}
if (n == "cls_ids") {
datas["classesName"] = $("#cls_ids option:selected").text();
}
}); $.ajax({
url: "addStudent",
type: 'POST',
data: datas,
success: function (arg) {
{# 将返回的信息,转化成数据#}
var mess = JSON.parse(arg);
if (mess.status) {
{#添加成功,刷新页面#}
{#window.location.reload()#}
{#添加成功,不刷新页面#}
createNewRecord(datas, mess.obj)
$("#addModal").modal('hide');
} else {
$("#errorMsg").text(mess.message)
}
}
})
}) } function createNewRecord(data, obj) {
var tr = document.createElement('tr');
$(tr).attr("nid", obj)
{#id#}
var tid = '<td na="entityId">' + obj + '</td>'; $(tr).append(tid);
{#姓名#}
var tName = '<td na="entityName">' + data.userName + '</td>';
$(tr).append(tName);
{#年龄#}
var tage = '<td na="entityAge">' + data.age + '</td>';
$(tr).append(tage);
{#性别#}
var tdGender = document.createElement('td');
$(tdGender).attr("na", "entityGender")
if (data.gender == "") {
tdGender.innerHTML = '女';
} else {
tdGender.innerHTML = '男';
}
$(tr).append(tdGender);
{#班级#}
var tdclassName = '<td na="entityClassName">' + data.classesName + '</td>';
$(tr).append(tdclassName);
var tdHandle = '<td><a class="glyphicon glyphicon-remove del-row"></a><i class="glyphicon glyphicon-pencil edit-row"></i></td>';
$(tr).append(tdHandle);
$('#tbStudentsList').append(tr);
} {#给删除按钮绑定,弹出模态窗口的事件#} function bindDel() {
{#点击每一行的删除链接#}
{#事件委托,解决新增的数据没有绑定删除事件的bug#}
$("#tbStudentsList").on("click", ".del-row", function () {
{#把删除的nid赋值给弹出窗口中的id#}
var rowId = $(this).parent().parent().attr('nid');
$("#delNid").val(rowId)
$("#delModal").modal('show');
})
{#弹出删除对话框后,取消按钮#}
$("#cancelConfirm").click(function () {
$("#delModal").modal('hide');
})
{#弹出删除确认对话框后,确定按钮#}
$("#delConfirm").click(function () {
var rowID = $("#delNid").val();
$.ajax({
url: "delStudent",
type: 'get',
data: {"rowID": rowID},
success: function (arg) {
{# 将返回的信息,转化成数据#}
var mess = JSON.parse(arg);
if (mess.status) {
{#删除成功,不刷新页面#}
$('tr[nid="' + rowID + '"]').remove();
}
$("#delModal").modal('hide');
}
}
)
}) } {#给编辑按钮绑定,弹出模态窗口的事件#} function bindEdit() {
{# 初始化页面,把要编辑的内容展示到页面上对应的字段#}
initEditModal();
{# 初始化页面,把要编辑的内容页面上的按钮进行事件绑定#}
bindEditSave();
} function initEditModal() {
{# 通过委托,来实现每一个编辑按钮的设置#}
$("#tbStudentsList").on('click', '.edit-row', function () {
clearEle()
$("#editModal").modal("show")
$(this).parent().prevAll().each(function () {
var tdName = $(this).attr('na')
var tdValue = $(this).text()
if (tdName == "entityClassName") {
$("#editModal #cls_ids option").each(function (i, n) {
if ($(n).text() == tdValue) {
$(n).attr("selected", true);
}
})
} else if (tdName == "entityGender") {
if (tdValue == '男') {
$('#editModal :radio[value="1"]').prop('checked', true);
} else {
$('#editModal :radio[value="0"]').prop('checked', true);
}
} else {
$("#editModal input[na='" + tdName + "']").val(tdValue)
}
}) })
} function bindEditSave() {
$("#editModal #btnSave").click(function () {
var datas = {}
{#遍历页面上所有的控件#}
$("#editModal #formStudentInfo").find("input,select").each(function () {
var v = $(this).val();
var n = $(this).attr('name');
if (n == "gender") {
if ($(this).prop("checked")) {
datas[n] = v;
}
} else {
datas[n] = v;
}
{#添加一个班级名称,方便后面不刷新页面直接显示的时候使用#}
if (n == "cls_ids") {
datas["classesName"] = $("#cls_ids option:selected").text();
}
});
$.ajax({
url: "editStudent",
type: 'POST',
data: datas,
{# 将返回的信息,转化成数据#}
dataType: 'JSON',
success: function (arg) {
if (arg.status) {
window.location.reload()
$("#addModal").modal('hide');
} else {
$("#errorMsg").text(arg.message)
}
}
})
}) } function clearEle() {
$("#addModal #formStudentInfo").find("input[type!='radio']").each(function () {
$(this).val('');
});
$("#editModal #formStudentInfo").find("input[type!='radio']").each(function () {
{#$(this).val('');#}
});
}
</script> </body>
</html>

html页面

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from App01 import models
import json def get_students(request):
stu_list = models.Students.objects.all()
cs_list = models.Classes.objects.all()
return render(request, "get_students.html", {'stu_list': stu_list, 'cs_list': cs_list}) def add_students(request):
if request.method == 'GET':
# 如果是通过get请求进来表示只是展示页面
cs_list = models.Classes.objects.all()
return render(request, "add_students.html", {'cs_list': cs_list})
elif request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cs')
models.Students.objects.create(
name=name,
age=age,
gender=gender,
cs_id=cs
)
return redirect("get_students.html") def del_students(request):
if request.method == 'GET':
nid = request.GET.get("nid")
models.Students.objects.filter(id=nid).delete()
return redirect("get_students.html") def edit_students(request):
if request.method == 'GET':
# 如果是通过get请求进来表示只是展示页面,注意需要将title值显示到文本框中
nid = request.GET.get("nid")
obj = models.Students.objects.filter(id=nid).first()
cs_list = models.Classes.objects.all()
return render(request, "edit_students.html", {'obj': obj, 'cs_list': cs_list})
elif request.method == 'POST':
nid = request.GET.get("nid")
name = request.POST.get('name')
age = request.POST.get('age')
gender = request.POST.get('gender')
cs = request.POST.get('cs')
models.Students.objects.filter(id=nid).update(name=name, age=age, gender=gender, cs_id=cs)
return redirect("get_students.html") def addStudent(request):
response = {"status":True,"message":None,"obj":None}
name = request.POST.get('userName')
age = request.POST.get('age')
gender = request.POST.get('gender')
if gender :
pass
else:
gender = 1
cs = request.POST.get('cls_ids') try:
print(name,age,gender,cs)
obj=models.Students.objects.create(
name=name,
age=age,
gender=gender,
cs_id=cs
)
response["obj"] = obj.id
print(response)
except:
response["status"]=False
response["message"]="输入的格式不正确"
# 把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)
return HttpResponse(result) def delStudent(request):
response = {"status": True, "message": None, "obj": None}
try:
nid = request.GET.get("rowID")
models.Students.objects.filter(id=nid).delete()
except:
response["status"] = False
response["message"] = "删除失败"
# 把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)
return HttpResponse(result) def editStudent(request):
response = {"status": True, "message": None, "obj": None}
nid = request.POST.get('nid')
name = request.POST.get('userName')
age = request.POST.get('age')
gender = request.POST.get('gender')
if gender:
pass
else:
gender = 1
cs = request.POST.get('cls_ids') try:
print(name, age, gender, cs)
models.Students.objects.filter(id=nid).update(name=name, age=age, gender=gender, cs_id=cs)
except:
response["status"] = False
response["message"] = "输入的格式不正确"
# 把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)
return HttpResponse(result)

students逻辑页面

11:分页功能

"""StudentManageSystem URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from App01.Views import classes,students,pagingTest
from django.conf.urls import url
urlpatterns = [
url('admin/', admin.site.urls),
# 班级管理 路由
url(r'^get_classes.html$',classes.get_classes),
url(r'^add_classes.html$',classes.add_classes),
url(r'^del_classes.html$', classes.del_classes),
url(r'^edit_classes.html$', classes.edit_classes),
# 为班级分配老师
url(r'^set_teachers.html$', classes.set_teachers),
# 学生管理 路由
url(r'^get_students.html$', students.get_students),
url(r'^add_students.html$', students.add_students),
url(r'^del_students.html$', students.del_students),
url(r'^edit_students.html$', students.edit_students),
# 学生管理2.0 路由
url(r'^addStudent$', students.addStudent),
url(r'^delStudent$', students.delStudent),
url(r'^editStudent$', students.editStudent),
# 分页测试 路由
url(r'^pagingTest1$', pagingTest.test1),
url(r'^pagingTest2$', pagingTest.test2),
]

分页路由

from django.shortcuts import render
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger
# 模拟数据
USER_LIST=[]
for i in range(1,666):
temp={'name':'root'+str(i),"age":i}
USER_LIST.append(temp)
def test1(request):
# 定义每页的显示数目
per_page_num=10
# 获取当前页码
current_page=request.GET.get('p')
current_page=int(current_page)
# 计算起始位置
start = (current_page-1)*per_page_num
end=current_page*per_page_num
data=USER_LIST[start:end]
# 定义上一页、下一页
prev_pager=current_page-1
next_pager=current_page+1
if current_page<=1:
prev_page=1
return render(request,'pagingTest1.html',{'user_list':data,'prev_pager':prev_pager,'next_pager':next_pager})
# django内部的分页
def test2(request):
# 全部数据 USER_LIST
# 每页显示条目数量 per_page
# 数据总个数 count
# 总页数的索引范围,如(1,10) page_range
# 是否具有下一页、上一页 page对象
current_page=request.GET.get("p")
paginator = Paginator(USER_LIST, 10)
try:
#Page对象
posts=paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_prev 是否有上一页
# prev_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator对象
except PageNotAnInteger:
posts=paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_page) return render(request,'pagingTest1.html',{'posts':posts})

分页逻辑

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
{% for row in posts %}
<li>{{ row.name }}--{{ row.age }}</li>
{% endfor %}
</ul>
{% if posts.has_previous %}
<a href="pagingTest2?p={{ posts.previous_page_number }}">上一页</a>
{% else %}
<a href="#">上一页</a>
{% endif %}
{% if posts.has_next %}
<a href="pagingTest2?p={{ posts.next_page_number }}">下一页</a>
{% else %}
<a href="#">下一页</a>
{% endif %}
{{ posts.number }}-{{ posts.paginator.num_pages }}
</body>
</html>

分页html

  我们还可以把分页的导航条单独放置到一个模板文件中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
{% for row in posts %}
<li>{{ row.name }}--{{ row.age }}</li>
{% endfor %}
</ul>
{% include 'include/page_par.html' %}
</body>
</html>
{% if posts.has_previous %}
<a href="pagingTest2?p={{ posts.previous_page_number }}">上一页</a>
{% else %}
<a href="#">上一页</a>
{% endif %}
{% if posts.has_next %}
<a href="pagingTest2?p={{ posts.next_page_number }}">下一页</a>
{% else %}
<a href="#">下一页</a>
{% endif %}
{{ posts.number }}/{{ posts.paginator.num_pages }}

page_par.html

  我们还可以添加页码条

from django.shortcuts import render
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger
# 模拟数据
USER_LIST=[]
for i in range(1,666):
temp={'name':'root'+str(i),"age":i}
USER_LIST.append(temp)
def test1(request):
# 定义每页的显示数目
per_page_num=10
# 获取当前页码
current_page=request.GET.get('p')
current_page=int(current_page)
# 计算起始位置
start = (current_page-1)*per_page_num
end=current_page*per_page_num
data=USER_LIST[start:end]
# 定义上一页、下一页
prev_pager=current_page-1
next_pager=current_page+1
if current_page<=1:
prev_page=1
return render(request,'pagingTest1.html',{'user_list':data,'prev_pager':prev_pager,'next_pager':next_pager})
# django内部的分页
def test3(request):
# 全部数据 USER_LIST
# 每页显示条目数量 per_page
# 数据总个数 count
# 总页数的索引范围,如(1,10) page_range
# 是否具有下一页、上一页 page对象
current_page=request.GET.get("p")
paginator = Paginator(USER_LIST, 10)
try:
#Page对象
posts=paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_prev 是否有上一页
# prev_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator对象
except PageNotAnInteger:
posts=paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_page) return render(request,'pagingTest1.html',{'posts':posts})
# 有导航条的分页
class MyPaginator(Paginator):
def __init__(self,current_page,total_page_par,*args,**kwargs):
# 当前页
self.current_page=int(current_page)
# 设置总的页码值
self.total_page_par=int(total_page_par)
super(MyPaginator,self).__init__(*args, **kwargs)
def page_par_range(self):
# 总页数( self.num_pages) 总页码数(self.total_page_par) 当前页(self.current_page)
# 如果总页数<总页码数
if self.num_pages<self.total_page_par:
return range(1,self.num_pages+1)
# 如果当前页数<总页码数/2
part = self.total_page_par//2
if self.current_page < part:
return range(1,self.total_page_par+1)
# 如果当前页+part >总页码数
if self.current_page+part>self.num_pages:
return range(self.num_pages-self.total_page_par+1,self.num_pages)
return range(self.current_page-part,self.current_page+part) def test2(request):
# 通过get获取当前页码
cur_page = request.GET.get("p")
print(cur_page)
try:
paginator = MyPaginator(cur_page, 11, USER_LIST, 10)
post=paginator.page(cur_page)
except PageNotAnInteger:
post=paginator.page(1)
except EmptyPage:
post=paginator.page(paginator.num_pages)
return render(request, 'pagingTest1.html', {'posts': post})

有导航条的分页

{% if posts.has_previous %}
<a href="pagingTest2?p={{ posts.previous_page_number }}">上一页</a>
{% else %}
<a href="#">上一页</a>
{% endif %}
{% for row_num in posts.paginator.page_par_range %} {% if row_num == posts.number %}
<a style="font-size: 30px;" href="/pagingTest2?p={{ row_num }}">{{ row_num }}</a>
{% else %}
<a href="pagingTest2?p={{ row_num }}">{{ row_num }}</a>
{% endif %} {% endfor %}
{% if posts.has_next %}
<a href="pagingTest2?p={{ posts.next_page_number }}">下一页</a>
{% else %}
<a href="#">下一页</a>
{% endif %}
{{ posts.number }}/{{ posts.paginator.num_pages }}

page_par.html

11:分页组件化

  我们可以自已定义一个分页组件 

  配置url:url(r'^myPageTest$', pagingTest.myPageTest), 

# 2.1 所需要的参数
# 序号 字段名 备注
# a data_count 列表的总个数
# b current_page_num当前页码
# C page_rows 每页显示多少行数据(每页显示10条)
# D page_num_size 页码条显示个数(建议为奇数,最多页面7个)
# 2.2 方法具有的内容
# 序号 字段名 备注
# 1 start 当前页列表显示的初始值
# 2 end 当前页列表显示的结束值
# 3 page_count 总页数
# 4 page_par_range 页码条显示范围 class AaronPager(object):
def __init__(self, data_count, current_page_num, page_rows=10, page_num_size=7):
# 数据总个数
self.data_count = data_count
# 当前页
try:
v = int(current_page_num)
if v <= 0:
v = 1
self.current_page_num = v
except Exception as e:
self.current_page_num = 1
# 每页显示的行数
self.page_rows = page_rows
# 最多显示页面
self.page_num_size = page_num_size def start(self):
return (self.current_page_num - 1) * self.page_rows def end(self):
return self.current_page_num * self.page_rows @property
def page_count(self):
# 总页数
a, b = divmod(self.data_count, self.page_rows)
if b == 0:
return a
return a + 1 def page_par_range(self):
# 总页数( self.page_count) 总页码数(self.page_num_size) 当前页(self.current_page_num)
# 如果总页数<总页码数
if self.page_count < self.page_num_size:
return range(1, self.page_count + 1)
# 如果当前页数<总页码数/2
part = self.page_num_size // 2
if self.current_page_num < part:
return range(1, self.page_num_size + 1)
# 如果当前页+part >总页码数
if self.current_page_num + part > self.page_count:
return range(self.page_count - self.page_num_size+1, self.page_count+1)
return range(self.current_page_num - part, self.current_page_num + part+1) def page_str(self):
page_list = []
first = "<li><a href='/myPageTest?p=1'>首页</a></li>"
page_list.append(first)
if self.current_page_num == 1:
prev = "<li><a href='#'>上一页</a></li>"
else:
prev = "<li><a href='/myPageTest?p=%s'>上一页</a></li>" % (self.current_page_num - 1)
page_list.append(prev)
for i in self.page_par_range():
if i==self.current_page_num:
temp = "<li class='active'><a href='/myPageTest?p=%s'>%s</a></li>" %(i,i)
else:
temp = "<li><a href='/myPageTest?p=%s'>%s</a></li>" %(i,i)
page_list.append(temp) if self.current_page_num == self.page_count:
nex = "<li><a href='#'>下一页</a></li>"
else:
nex = "<li><a href='/myPageTest?p=%s'>下一页</a></li>" %(self.current_page_num + 1)
page_list.append(nex)
last = "<li><a href='/myPageTest?p=%s'>尾页</a></li>" %(self.page_count)
page_list.append(last) return ''.join(page_list)

AaronPager

from django.shortcuts import render
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger
# 模拟数据
USER_LIST=[]
for i in range(1,666):
temp={'name':'root'+str(i),"age":i}
USER_LIST.append(temp)
def test1(request):
# 定义每页的显示数目
per_page_num=10
# 获取当前页码
current_page=request.GET.get('p')
current_page=int(current_page)
# 计算起始位置
start = (current_page-1)*per_page_num
end=current_page*per_page_num
data=USER_LIST[start:end]
# 定义上一页、下一页
prev_pager=current_page-1
next_pager=current_page+1
if current_page<=1:
prev_page=1
return render(request,'pagingTest1.html',{'user_list':data,'prev_pager':prev_pager,'next_pager':next_pager})
# django内部的分页
def test3(request):
# 全部数据 USER_LIST
# 每页显示条目数量 per_page
# 数据总个数 count
# 总页数的索引范围,如(1,10) page_range
# 是否具有下一页、上一页 page对象
current_page=request.GET.get("p")
paginator = Paginator(USER_LIST, 10)
try:
#Page对象
posts=paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_prev 是否有上一页
# prev_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator对象
except PageNotAnInteger:
posts=paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_page) return render(request,'pagingTest1.html',{'posts':posts})
# 有导航条的分页
class MyPaginator(Paginator):
def __init__(self,current_page,total_page_par,*args,**kwargs):
# 当前页
self.current_page=int(current_page)
# 设置总的页码值
self.total_page_par=int(total_page_par)
super(MyPaginator,self).__init__(*args, **kwargs)
def page_par_range(self):
# 总页数( self.num_pages) 总页码数(self.total_page_par) 当前页(self.current_page)
# 如果总页数<总页码数
if self.num_pages<self.total_page_par:
return range(1,self.num_pages+1)
# 如果当前页数<总页码数/2
part = self.total_page_par//2
if self.current_page < part:
return range(1,self.total_page_par+1)
# 如果当前页+part >总页码数
if self.current_page+part>self.num_pages:
return range(self.num_pages-self.total_page_par+1,self.num_pages)
return range(self.current_page-part,self.current_page+part) def test2(request):
# 通过get获取当前页码
cur_page = request.GET.get("p")
print(cur_page)
try:
paginator = MyPaginator(cur_page, 11, USER_LIST, 10)
post=paginator.page(cur_page)
except PageNotAnInteger:
post=paginator.page(1)
except EmptyPage:
post=paginator.page(paginator.num_pages)
return render(request, 'pagingTest1.html', {'posts': post}) def myPageTest(request):
from App01.AaronPager import AaronPager
data_count=666
cur_page=request.GET.get("p")
aaron_page = AaronPager(data_count,cur_page,10,7)
data_list = USER_LIST[aaron_page.start():aaron_page.end()]
return render(request,'aaronTest.html',{'data':data_list,'aaron_page':aaron_page})

pagingTest.py处理业务逻辑

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css">
</head>
<body>
<ul>
{% for row in data %}
<li>{{ row.name }}--{{ row.age }}</li>
{% endfor %}
</ul>
{% for i in aaron_page.page_par_range %}
<a href="/myPageTest?p={{ i }}">{{ i }}</a>
{% endfor %} <ul class="pagination pagination-sm">
{{ aaron_page.page_str|safe }}
</ul> </body>
</html>

aaronTest.html

饮冰三年-人工智能-Python-26 Django 学生管理系统的更多相关文章

  1. 饮冰三年-人工智能-Python-22 Python初识Django

    1:一个简单的web框架 # 导包 from wsgiref.simple_server import make_server #自定义个处理函数 def application(environ,st ...

  2. 饮冰三年-人工智能-Python-21 Python数据库MySql

    一:下载与安装 1:下载地址:https://dev.mysql.com/downloads/mysql/ 2:安装MySql 打开下载文件解压到指定文件目录.(我这里解压目录为D:\MySql\my ...

  3. 饮冰三年-人工智能-Python-30 python开发中常见的错误

    1:触发条件:创建的实体类生成到数据库表时报错 报错信息:TypeError: __init__() missing 1 required positional argument: 'on_delet ...

  4. 饮冰三年-人工智能-Python-25 Django admin

    简介:一个关于后台数据库管理的工具 1:创建一个新的项目 2:设置models,并通过命令生成数据库表 from django.db import models class Book(models.M ...

  5. 饮冰三年-人工智能-Python-24 Django ORM增删改查

    一:首先使用默认的sqlite3创建表 1:现在在models.py中添加表模型 from django.db import models # Create your models here. cla ...

  6. 饮冰三年-人工智能-Python-27 Django Form组件

    Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 后台逻辑(导包+建类) from django ...

  7. 饮冰三年-人工智能-Python-23 Python PyCharm 使用中常见的问题

    一:软件工具使用中遇到的问题 1:AttributeError: module 'pip' has no attribute 'main'问题 处理方法: a:找到JetBrains\PyCharm ...

  8. 饮冰三年-人工智能-Python-20 Python线程、进程、线程

    进程:最小的数据单元 线程:最小的执行单元 一: 1:线程1 import threading #线程 import time def Music(): print("Listen Musi ...

  9. 饮冰三年-人工智能-Python-19 Python网络编程

    Socket:套接字.作用:我们只需要安照socket的规定去编程,就不需要深入理解tcp/udp协议也可以实现 1:TCP协议 1.1  客户端服务端循环收发消息 # 1:引入stock模块(导包) ...

随机推荐

  1. BZOJ3527[Zjoi2014]力——FFT

    题目描述 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. 输入 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. n≤100000,0<qi<100000 ...

  2. Git-01-上传项目到github

    function fun1(){ Git上传项目到github Folder-->Git bash here Execute command: --git clone 仓库地址     多出一个 ...

  3. Gitlab安装简明文档

    1.关于Gitlab CE / GitLab EE版本的区别:Gitlab CE(Community Edition):Gitlab社区版,可以免费试用,无官方支持.GitLab EE(Enterpr ...

  4. Python中eval函数的作用

    eval eval函数就是实现list.dict.tuple与str之间的转化str函数把list,dict,tuple转为为字符串# 字符串转换成列表a = "[[1,2], [3,4], ...

  5. selenium各版本jar包下载地址

    http://selenium-release.storage.googleapis.com/index.html

  6. 微信小程序 开发文档

    官方开发文档: 小程序公众平台 小程序开发者指南 小程序开发者文档 学习资源: 微信:官方入门教程 微信:WeUI 是一套同微信原生视觉体验一致的基础样式库 微信:微信小程序示例 视频: 学堂在线:学 ...

  7. 如何为 Jupyter Notebook 安装代码提示功能

    按照上一篇博客安装完 Python 和 Jupyter Notebook 后,我们已经可以使用 Notebook 愉快的编写 Python 代码了,但是发现它不像其他编辑器那样会弹出代码提示,这稍微有 ...

  8. Java调用第三方http接口的方式

    1. 概述 在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适.很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信.天气等). 在J ...

  9. 五十六、linux 编程——UDP 编程模型

    56.1 UDP 编程模型 56.1.1 编程模型 UDP 协议称为用户数据报文协议,可靠性比 TCP 低,但执行效率高 56.1.2 API (1)发送数据 函数参数: sockfs:套接字文件描述 ...

  10. ES2015 中的函数式Mixin

    原文链接:http://raganwald.com/2015/06/17/functional-mixins.html 在“原型即对象”中,我们看到可以对原型使用 Object.assign 来模拟 ...