背景:创建一个简单的学生管理系统,熟悉增删改查操作
一:创建一个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")
c:html页面模板设置
"en"> "UTF-8">Title "1">
{ % for row in cls_list %} ID 名称 操作 { % endfor %} { { row.id }} { { row.title }} "/del_classes.html?nid={ {row.id}}">删除 | "/edit_classes.html?nid={ {row.id}}">编辑
"en"> "UTF-8">Title
"en"> "UTF-8">Title
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) ]
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")
c:html页面模板设置
"en"> "UTF-8">Title "1">
{ % for row in stu_list %} ID 姓名 年龄 性别 班级 操作 { % endfor %} { { row.id }} { { row.name }} { { row.age }} { % if row.gender %}男 { % else %}女 { % endif %}{ { row.cs.title }} "/del_students.html?nid={ {row.id}}">删除 | "/edit_students.html?nid={ {row.id}}">编辑
"en"> "UTF-8">Title
"en"> "UTF-8">Title
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")
c:html页面模板设置
"en"> "UTF-8">Title
"en"> "UTF-8">Title "1">
{ % for row in cls_list %} ID 名称 任课老师 操作 { % endfor %} { { row.id }} { { row.title }} { % for item in row.m.all %} { { item.name }} { % endfor %} "/del_classes.html?nid={ {row.id}}">删除 | "/edit_classes.html?nid={ {row.id}}">编辑 | "/set_teachers.html?nid={ {row.id}}">分配教师
学生管理系统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'), )
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), ]
5:学生页面
"en"> "UTF-8">Title { #引入css和Bootstrap#} "stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css"> "stylesheet" href="/static/plugins/fontawesome/css/fontawesome.css">class="container"> class="btn btn-primary" id="addBtn">添加 class="btn btn-danger" id="delBtn">删除class="table table-hover table-bordered">
{ % for row in stu_list %} ID 姓名 年龄 性别 班级 操作 { % endfor %} { { row.id }} { { row.name }} { { row.age }} { % if row.gender %}男 { % else %}女 { % endif %}{ { row.cs.title }} class="glyphicon glyphicon-remove"> class="glyphicon glyphicon-pencil"> class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">{ #引入jQuery和Bootstrap#}class="modal-dialog" role="document">class="modal-content">class="modal-header">class="modal-title" id="myModalLabel">学生信息
class="modal-body">class="modal-footer"> "errorMsg" style="color: red">
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)
7:显示效果
8:修改HTML页面中的js,使得数据添加成功后,不刷新页面
主要实现原理是:ajax回调成功后,拼接一个tr,添加到原来的table中
9:删除功能以及删除bug修改
# 学生管理2.0 路由 url(r'^addStudent$', students.addStudent), url(r'^delStudent$', students.delStudent),
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)
"en"> "UTF-8">Title { #引入css和Bootstrap#} "stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css"> "stylesheet" href="/static/plugins/fontawesome/css/fontawesome.css">class="container"> class="btn btn-primary" id="addBtn">添加 class="btn btn-danger" id="delBtn">删除"tbStudentsList" class="table table-hover table-bordered">
{ % for row in stu_list %} ID 姓名 年龄 性别 班级 操作 "{ { row.id }}"> { % endfor %}{ { row.id }} { { row.name }} { { row.age }} { % if row.gender %}男 { % else %}女 { % endif %}{ { row.cs.title }} class="glyphicon glyphicon-remove del-row"> class="glyphicon glyphicon-pencil"> class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">class="modal-dialog" role="document">class="modal-content">class="modal-header">class="modal-title" id="myModalLabel">学生信息
class="modal-body">class="modal-footer"> "errorMsg" style="color: red">class="modal fade" id="delModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">{ #引入jQuery和Bootstrap#}class="modal-dialog" role="document">class="alert alert-danger" role="alert">删除学生信息?
..."display: none;" type="text" id="delNid"/>
存在的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); }
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'); } } ) }) }
10:编辑功能
"en"> "UTF-8">Title { #引入css和Bootstrap#} "stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css"> "stylesheet" href="/static/plugins/fontawesome/css/fontawesome.css">class="container"> class="btn btn-primary" id="addBtn">添加 class="btn btn-danger" id="delBtn">删除"tbStudentsList" class="table table-hover table-bordered">
{ % for row in stu_list %} ID 姓名 年龄 性别 班级 操作 "{ { row.id }}"> { % endfor %}"entityId">{ { row.id }} "entityName">{ { row.name }} "entityAge">{ { row.age }} { % if row.gender %}"entityGender">男 { % else %}"entityGender">女 { % endif %}"entityClassName">{ { row.cs.title }} class="glyphicon glyphicon-remove del-row"> class="glyphicon glyphicon-pencil edit-row"> class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">class="modal-dialog" role="document">class="modal-content">class="modal-header">class="modal-title" id="myModalLabel">学生信息
class="modal-body">class="modal-footer"> "errorMsg" style="color: red">class="modal fade" id="delModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">class="modal-dialog" role="document">class="alert alert-danger" role="alert">删除学生信息?
..."display: none;" type="text" id="delNid"/>class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">{ #引入jQuery和Bootstrap#}class="modal-dialog" role="document">class="modal-content">class="modal-header">class="modal-title" id="myModalLabel">学生信息
class="modal-body">class="modal-footer"> "errorMsg" style="color: red">
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)
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})
"en"> "UTF-8">Title
-
{
% for row in posts %}
- { { row.name }}--{ { row.age }} { % endfor %}
我们还可以把分页的导航条单独放置到一个模板文件中
"en"> "UTF-8">Title
-
{
% for row in posts %}
- { { row.name }}--{ { row.age }} { % endfor %}
{% if posts.has_previous %} "pagingTest2?p={ { posts.previous_page_number }}">上一页 { % else %} "#">上一页 { % endif %} { % if posts.has_next %} "pagingTest2?p={ { posts.next_page_number }}">下一页 { % else %} "#">下一页 { % endif %} { { posts.number }}/{ { posts.paginator.num_pages }}
我们还可以添加页码条
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 %} "pagingTest2?p={ { posts.previous_page_number }}">上一页 { % else %} "#">上一页 { % endif %} { % for row_num in posts.paginator.page_par_range %} { % if row_num == posts.number %} "font-size: 30px;" href="/pagingTest2?p={ { row_num }}">{ { row_num }} { % else %} "pagingTest2?p={ { row_num }}">{ { row_num }} { % endif %} { % endfor %} { % if posts.has_next %} "pagingTest2?p={ { posts.next_page_number }}">下一页 { % else %} "#">下一页 { % endif %} { { posts.number }}/{ { posts.paginator.num_pages }}
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 = "首页 " page_list.append(first) if self.current_page_num == 1: prev = "上一页 " else: prev = "上一页 " % (self.current_page_num - 1) page_list.append(prev) for i in self.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)
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})
"en"> "UTF-8">Title "stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css">
-
{
% for row in data %}
- { { row.name }}--{ { row.age }} { % endfor %}
- class="pagination pagination-sm">
{
{ aaron_page.page_str|safe }}