背景:创建一个简单的学生管理系统,熟悉增删改查操作
一:创建一个Django项目(http://www.cnblogs.com/wupeiqi/articles/6216618.html)
1:创建实体类
from django.db importmodels#Create your models here.
classClasses(models.Model):#班级表
title=models.CharField(max_length=32)#班级-教师:多对多
m=models.ManyToManyField("Teachers")classTeachers(models.Model):#教师表
name = models.CharField(max_length=32)classStudents(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 importadminfrom django.urls importpathfrom App01.Views importclassesfrom django.conf.urls importurl
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 importrenderfrom django.shortcuts importHttpResponsefrom django.shortcuts importredirectfrom App01 importmodelsdefget_classes(request):
cls_list=models.Classes.objects.all()return render(request,"get_classes.html",{'cls_list':cls_list})defadd_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")defdel_classes(request):if request.method=='GET':
nid= request.GET.get("nid")
models.Classes.objects.filter(id=nid).delete()return redirect("get_classes.html")defedit_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页面模板设置
Titleget_classes.html
Title{% csrf_token %}add_classes.html
Title{% csrf_token %}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 importadminfrom django.urls importpathfrom App01.Views importclasses,studentsfrom django.conf.urls importurl
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 importrenderfrom django.shortcuts importHttpResponsefrom django.shortcuts importredirectfrom App01 importmodelsdefget_students(request):
stu_list=models.Students.objects.all()return render(request,"get_students.html",{'stu_list':stu_list})defadd_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")defdel_students(request):if request.method=='GET':
nid= request.GET.get("nid")
models.Students.objects.filter(id=nid).delete()return redirect("get_students.html")defedit_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页面模板设置
TitleID姓名年龄性别班级操作
{% for row in stu_list %}{{ row.id }}{{ row.name }}{{ row.age }}{% if row.gender %}男{% else %}女{% endif %}{{ row.cs.title }}|
{% endfor %}get_students.html
Title{% csrf_token %}男女
{% for row in cs_list %}{{ row.title }}{% endfor %}
add_students.html
Title{% csrf_token %}{#
{% if obj.gender %}
男:女:{% else %}
男:女:{% endif %}
{% for row in cs_list %}
{% if row.id == obj.cs_id %}{{ row.title }}{% else %}{{ row.title }}{% endif %}
{% endfor %}
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(111)
print(selectTeacherIds)
models.Classes.objects.filter(id=nid).first().m.set(selectTeacherIds)return redirect("get_classes.html")
在classesview中添加方法
c:html页面模板设置
Title{% csrf_token %}{% for teacher in teachersList %}{% if teacher in selectTeacherList %}{{ teacher.name }}{% else %}{{ teacher.name }}{% endif %}
{% endfor %}
set_teachers.html
TitleID名称任课老师操作
{% for row in cls_list %}{{ row.id }}{{ row.title }}{% for item in row.m.all %} {{ item.name }}{% endfor %}|
|
{% endfor %}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/"""
importos#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 importadminfrom django.urls importpathfrom App01.Views importclasses,studentsfrom django.conf.urls importurl
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:学生页面
Title{#引入css和Bootstrap#}ID姓名年龄性别班级操作
{% for row in stu_list %}{{ row.id }}{{ row.name }}{{ row.age }}{% if row.gender %}男{% else %}女{% endif %}{{ row.cs.title }} {% endfor %}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)
}
}
})
})
}
get_students.html
6:后台处理页面
from django.shortcuts importrenderfrom django.shortcuts importHttpResponsefrom django.shortcuts importredirectfrom App01 importmodelsimportjsondefget_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})defadd_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")defdel_students(request):if request.method == 'GET':
nid= request.GET.get("nid")
models.Students.objects.filter(id=nid).delete()return redirect("get_students.html")defedit_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")defaddStudent(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路由设置
defaddStudent(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.idprint(response)except:
response["status"]=False
response["message"]="输入的格式不正确"
#把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)returnHttpResponse(result)defdelStudent(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)
逻辑层,逻辑控制
Title{#引入css和Bootstrap#}ID姓名年龄性别班级操作
{% for row in stu_list %}{{ row.id }}{{ row.name }}{{ row.age }}{% if row.gender %}男{% else %}女{% endif %}{{ row.cs.title }} {% endfor %}删除学生信息?
取消
确定
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 = '
' + obj + '';$(tr).append(tid);
{#姓名#}
var tName = '
' + data.userName + '';$(tr).append(tName);
{#年龄#}
var tage = '
' + data.age + '';$(tr).append(tage);
{#性别#}
var tdGender = document.createElement('td');if (data.gender == "0") {
tdGender.innerHTML= '女';
}else{
tdGender.innerHTML= '男';
}
$(tr).append(tdGender);
{#班级#}
var tdclassName = '
' + data.classesName + '';$(tr).append(tdclassName);
var tdHandle= '
';$(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');
}
}
)
})
}
html
存在的bug:新增之后,再次点击删除,发现没有触发事件。
原因分析:页面没有重新加载,绑定事件没有触发。可以通过事件委托来实现
function createNewRecord(data, obj) {
var tr= document.createElement('tr');
$(tr).attr("nid",obj)
{#id#}
var tid = '
' + obj + '';$(tr).append(tid);
{#姓名#}
var tName = '
' + data.userName + '';$(tr).append(tName);
{#年龄#}
var tage = '
' + data.age + '';$(tr).append(tage);
{#性别#}
var tdGender = document.createElement('td');if (data.gender == "0") {
tdGender.innerHTML= '女';
}else{
tdGender.innerHTML= '男';
}
$(tr).append(tdGender);
{#班级#}
var tdclassName = '
' + data.classesName + '';$(tr).append(tdclassName);
var tdHandle= '
';$(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:编辑功能
Title{#引入css和Bootstrap#}ID姓名年龄性别班级操作
{% for row in stu_list %}{{ row.id }}{{ row.name }}{{ row.age }}{% if row.gender %}男{% else %}女{% endif %}{{ row.cs.title }} {% endfor %}删除学生信息?
取消
确定
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 = '
' + obj + '';$(tr).append(tid);
{#姓名#}
var tName = '
' + data.userName + '';$(tr).append(tName);
{#年龄#}
var tage = '
' + data.age + '';$(tr).append(tage);
{#性别#}
var tdGender = document.createElement('td');
$(tdGender).attr("na", "entityGender")if (data.gender == "0") {
tdGender.innerHTML= '女';
}else{
tdGender.innerHTML= '男';
}
$(tr).append(tdGender);
{#班级#}
var tdclassName = '
' + data.classesName + '';$(tr).append(tdclassName);
var tdHandle= '
';$(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('');#}
});
}
html页面
from django.shortcuts importrenderfrom django.shortcuts importHttpResponsefrom django.shortcuts importredirectfrom App01 importmodelsimportjsondefget_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})defadd_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")defdel_students(request):if request.method == 'GET':
nid= request.GET.get("nid")
models.Students.objects.filter(id=nid).delete()return redirect("get_students.html")defedit_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")defaddStudent(request):
response= {"status":True,"message":None,"obj":None}
name= request.POST.get('userName')
age= request.POST.get('age')
gender= request.POST.get('gender')ifgender :pass
else:
gender= 1cs= 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.idprint(response)except:
response["status"]=False
response["message"]="输入的格式不正确"
#把返回的数据信息先转化成字符串
result = json.dumps(response, ensure_ascii=False)returnHttpResponse(result)defdelStudent(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)returnHttpResponse(result)defeditStudent(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')ifgender:pass
else:
gender= 1cs= 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 importadminfrom django.urls importpathfrom App01.Views importclasses,students,pagingTestfrom django.conf.urls importurl
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 importrenderfrom django.core.paginator importPaginator,EmptyPage,PageNotAnInteger#模拟数据
USER_LIST=[]for i in range(1,666):
temp={'name':'root'+str(i),"age":i}
USER_LIST.append(temp)deftest1(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-1next_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内部的分页
deftest2(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对象
exceptPageNotAnInteger:
posts=paginator.page(1)exceptEmptyPage:
posts=paginator.page(paginator.num_page)return render(request,'pagingTest1.html',{'posts':posts})
分页逻辑
Title- {% for row in posts %}
- {{ row.name }}--{{ row.age }}{% endfor %}
{% if posts.has_next %}下一页{% else %}下一页{% endif %}
{{ posts.number }}-{{ posts.paginator.num_pages }}
分页html
我们还可以把分页的导航条单独放置到一个模板文件中
Title- {% for row in posts %}
- {{ row.name }}--{{ row.age }}{% endfor %}
View Code
{% if posts.has_previous %}上一页{% else %}上一页{% endif %}
{% if posts.has_next %}下一页{% else %}下一页{% endif %}
{{ posts.number }}/{{ posts.paginator.num_pages }}
page_par.html
我们还可以添加页码条
from django.shortcuts importrenderfrom django.core.paginator importPaginator,EmptyPage,PageNotAnInteger#模拟数据
USER_LIST=[]for i in range(1,666):
temp={'name':'root'+str(i),"age":i}
USER_LIST.append(temp)deftest1(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-1next_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内部的分页
deftest3(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对象
exceptPageNotAnInteger:
posts=paginator.page(1)exceptEmptyPage:
posts=paginator.page(paginator.num_page)return render(request,'pagingTest1.html',{'posts':posts})#有导航条的分页
classMyPaginator(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)defpage_par_range(self):#总页数( self.num_pages) 总页码数(self.total_page_par) 当前页(self.current_page)#如果总页数
if self.num_pages
part = self.total_page_par//2
if self.current_page 总页码数
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)deftest2(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)exceptPageNotAnInteger:
post=paginator.page(1)exceptEmptyPage:
post=paginator.page(paginator.num_pages)return render(request, 'pagingTest1.html', {'posts': post})
有导航条的分页
{% if posts.has_previous %}上一页{% else %}上一页{% endif %}
{% for row_num in posts.paginator.page_par_range %}
{% if row_num == posts.number %}{{ row_num }}{% else %}{{ row_num }}{% endif %}
{% endfor %}
{% if posts.has_next %}下一页{% else %}下一页{% 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 页码条显示范围
classAaronPager(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= 1self.current_page_num=vexceptException as e:
self.current_page_num= 1
#每页显示的行数
self.page_rows =page_rows#最多显示页面
self.page_num_size =page_num_sizedefstart(self):return (self.current_page_num - 1) *self.page_rowsdefend(self):return self.current_page_num *self.page_rows
@propertydefpage_count(self):#总页数
a, b =divmod(self.data_count, self.page_rows)if b ==0:returnareturn a + 1
defpage_par_range(self):#总页数( self.page_count) 总页码数(self.page_num_size) 当前页(self.current_page_num)
#如果总页数
if self.page_count
part = self.page_num_size // 2
if self.current_page_num 总页码数
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)defpage_str(self):
page_list=[]
first= "
首页"page_list.append(first)if self.current_page_num == 1:prev= "
上一页"else:
prev= "
上一页" % (self.current_page_num - 1)page_list.append(prev)for i inself.page_par_range():if i==self.current_page_num:
temp= "
%s" %(i,i)else:temp= "
%s" %(i,i)page_list.append(temp)if self.current_page_num ==self.page_count:
nex= "
下一页"else:
nex= "
下一页" %(self.current_page_num + 1)page_list.append(nex)
last= "
尾页" %(self.page_count)page_list.append(last)return ''.join(page_list)
AaronPager
from django.shortcuts importrenderfrom django.core.paginator importPaginator,EmptyPage,PageNotAnInteger#模拟数据
USER_LIST=[]for i in range(1,666):
temp={'name':'root'+str(i),"age":i}
USER_LIST.append(temp)deftest1(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-1next_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内部的分页
deftest3(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对象
exceptPageNotAnInteger:
posts=paginator.page(1)exceptEmptyPage:
posts=paginator.page(paginator.num_page)return render(request,'pagingTest1.html',{'posts':posts})#有导航条的分页
classMyPaginator(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)defpage_par_range(self):#总页数( self.num_pages) 总页码数(self.total_page_par) 当前页(self.current_page)#如果总页数
if self.num_pages
part = self.total_page_par//2
if self.current_page 总页码数
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)deftest2(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)exceptPageNotAnInteger:
post=paginator.page(1)exceptEmptyPage:
post=paginator.page(paginator.num_pages)return render(request, 'pagingTest1.html', {'posts': post})defmyPageTest(request):from App01.AaronPager importAaronPager
data_count=666cur_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处理业务逻辑
Title- {% for row in data %}
- {{ row.name }}--{{ row.age }}{% endfor %}
- {{ aaron_page.page_str|safe }}
aaronTest.html