Ajax(Asynchronous JavaScript and XML),直译为“异步的JavaScript与XML技术”,是一种创建交互式网页应用的网页开发技术,用于创建快速动态网页,由杰西·詹姆士·贾瑞特所提出。
好处:与传统的Web应用相比,Ajax通过浏览器与服务器进行少量的数据交换就可以实现网页的异步更新,在不重新加载整个网页的情况下,即可对网页进行更新。
注:此篇文章主要使用了flask框架应用MVC架构的后台管理界面功能的实现,即对数据库进行异步的增删改查操作。
文件架构(一个 “—” 代表第一层文件目录,两个"——"代表第二层):
bs_ly_flask(本文章项目名)
—controller(控制层文件夹)
——usercontroller.py(控制层文件,其方法均为装饰器函数,控制视图层中各种对数据的操作)
—dao(连接数据库的文件夹)
——basedao.py(连接数据库以及提供通用的数据库接口文件)
——pymysql.json(数据库信息配置文件)
——userdao.py(提供执行sql增删改查方法的文件)
—entity(封装实体的文件夹)
——user.py(初始化用户实体属性的文件)
—service(为控制层提供服务的文件夹)
——userservice.py(接收控制层传来的数据,调用userdao.py文件中的方法对数据进行处理,然后将其返回给控制层;其中,查询操作在返回时,需要进行实体封装后再进行返回)
—static(存放各种js、css以及img子文件夹)
——img(文件夹,存放前端界面的各种图片)
——js(文件夹,存放.js文件)
——css(存放.css文件)
—templates(存放各种.html用户界面)
——systeminfo(文件夹,主要存放后台界面)
—app.py(启动程序文件)
以上则是本次flask项目的大体文件架构。
以下为各个文件的具体代码实现,各文件顺序与文件架构中的顺序相同:
usercontroller.py文件(此文件为未删减版):
from flask import render_template,Response,Blueprint,session,request
from service.userservice import UserService
from entity.user import User
import json
usercontroller = Blueprint('usercontroller',__name__)
userService=UserService()
@usercontroller.route('/login.do',methods=['POST','GET'])
def login():
username = request.form.get('username')
userpwd = request.form.get('userpwd')
result = userService.findUserByUserName(username) #去数据库里找
if result and result[0][2]==userpwd:
session["username"]=username
resp = Response(render_template("index.html",message="登陆成功"))
resp.set_cookie('username',username,max_age=7*24*3600)
resp.set_cookie('userpwd',userpwd,max_age=7*24*3600)
return resp
elif result and result[0][2]!=userpwd:
return render_template("login.html",message='用户名或密码错误!!!')
return render_template("login.html")
pass
@usercontroller.route('/logout.do',methods=['POST','GET'])
def logout():
session.clear()
resp = Response(render_template("index.html"))
resp.delete_cookie('username')
resp.delete_cookie('userpwd')
return resp
pass
@usercontroller.route('/goRegister.do') #用户点击注册按钮去注册界面
def goRegister():
return render_template('register.html')
@usercontroller.route('/register.do',methods=['POST','GET'])
def register():
username = request.form.get('username')
userpwd = request.form.get('pword')
reuserpwd = request.form.get('repword')
zsusername = request.form.get('zsname')
ages = request.form.get('ages')
sex = request.form.get('sexx')
telphone=request.form.get('telphone')
city = request.form.get('city')
xxdz = request.form.get('xxdz')
user=User()
user.userName = username
user.userPwd = userpwd
user.reUserPwd = reuserpwd
user.zsUserName = zsusername
user.ages = ages
user.sex = sex
user.telphone = telphone
user.city = city
user.xxdz = xxdz
result = userService.createUser(user)
if result>0:
return render_template("login.html",message="注册成功")
else:
return render_template("register.html",message="注册失败")
pass
#管理员登陆验证暂时未写,便于测试
@usercontroller.route('/mglogin.do',methods=['POST','GET'])
def mglogin():
return render_template("mglogin.html")
pass
@usercontroller.route('/mgrigister.do',methods=['POST','GET'])
def mgrigister():
return render_template("mgrigister.html")
pass
#查询用户信息并显示:支持其中一个条件满足,也支持同时满足。
@usercontroller.route('/gouserinfo.do',methods=['POST','GET'])
def goUserInfo():
userName = request.form.get('userName')
userCity = request.form.get('userCity')
user = User()
user.userName = userName
user.city = userCity
userList = userService.findUserList(user)
return render_template('systeminfo/messageinfo.html', userList=userList, user=user) # 前端用的key
#删除功能
@usercontroller.route('/removeuser.do',methods = ['POST','GET'])
def goRemoveUser():
userId = request.args.get('userId')
userName = request.form.get('userName')
userCity = request.form.get('userCity')
user = User()
user.userName = userName
user.city = userCity
result = userService.removeUser(userId)
userList = userService.findUserList(user)
return render_template('systeminfo/messageinfo.html',userList=userList,message="删除成功" if result>0 else "删除失败") #前端用的key
#修改
@usercontroller.route('/checkusername.do',methods = ['POST','GET'])
def checkUserName():
userdata = request.get_data()
userDict = json.loads(userdata)
user = User()
user.userId = userDict.get('userId') #将数据赋给user实体的属性
user.userName=userDict.get('userName')
user.zsUserName = userDict.get('userzsname')
user.ages = userDict.get('userages')
user.sex = userDict.get('usersex')
user.telphone =userDict.get('usertelphone')
user.city = userDict.get('usercity')
user.xxdz = userDict.get('userxxdz')
result = userService.updateUser(user) #
dicts={}
if result:
dicts = {'code':1}
else:
dicts = {'code':0}
return json.dumps(dicts)
pass
#其实增删改查事务都可在这里写,有兴趣的小白可以去尝试
@usercontroller.route('/ajaxuserinfo.do', methods=['POST', 'GET'])
def getUserInfo():
userData = request.get_data()
userDict = json.loads(userData)
tData = {}
user = User()
user.userName = userDict.get('userName')
user.city = userDict.get('userCity')
currentPage = int(userDict.get('currentPage'))
pageSize = int(userDict.get('pageSize'))
opr = userDict.get('opr')
userId = int(userDict.get('userId'))
user.userId = userId
result = userService.findPageUserList(user, pageSize, currentPage)
counts = userService.countUsers(user)
totalPage = 0
if(counts%pageSize == 0):
totalPage = counts//pageSize
else:
totalPage = counts // pageSize + 1
pass
returnData = {'code':1, 'userData':result, 'pageSize':pageSize, 'currentPage':currentPage, 'totalPage':totalPage, 'opr':'search'}
return json.dumps(returnData)
pass
basedao.py文件(封装了一些对数据库操作的通用方法):
import pymysql
import json
import os
#DBUtils.py
class BaseDao():
def __init__(self,configPath = 'pymysql.json'):
self.__connection =None
self.__cursor = None
self.__config = json.load(open(os.path.dirname(__file__) + os.sep + configPath,'r')) #通过json配置获得数据的连接配置信息
print(self.__config)
pass
def getConnection(self):
#当有连接对象时,直接返回连接对象
if self.__connection:
return self.__connection
#否则通过建立新的连接对象
try:
self.__connection = pymysql.connect(**self.__config)
return self.__connection
except pymysql.MySQLError as e:
print("Exception"+str(e))
pass
pass
#用于执行Sql语句的通用方法
def execute(self,sql,params=None):
try:
self.__cursor = self.getConnection().cursor()
#execute:返回的是修改数据的条数
if params:
result = self.__cursor.execute(sql,params)
else:
result = self.__cursor.execute(sql)
return result
except (pymysql.MySQLError,pymysql.DatabaseError,Exception) as e:#捕获多个异常
print("出现数据库访问异常:"+str(e))
self.rollback()
pass
pass
pass
def fetch(self):
if self.__cursor: #提高代码健壮性
return self.__cursor.fetchall()
pass
def fetchOne(self):
if self.__cursor: #提高代码健壮性
return self.__cursor.fetchone()
pass
def commit(self):
if self.__connection:
self.__connection.commit() #回滚问题
pass
def rollback(self):
if self.__connection:
self.__connection.rollback()
pass
def getLastRowId(self):
if self.__cursor:
return self.__cursor.lastrowid
def close(self):
if self.__cursor:
self.__cursor.close()
if self.__connection:
self.__connection.close()
pass
if __name__=="__main__":
ms = BaseDao()
pymysql.json文件(数据库配置信息)
{"host":"127.0.0.1","user":"root","password":"root", "database" :"你的数据库","port":你的数据库密码}
userdao.py文件(为未删减版)
from .basedao import BaseDao
class UserDao(BaseDao):
def findUserByUserName(self,userName):
try:
sql="select * from ly_user where user_name=%s"
self.getConnection()
self.execute(sql,(userName,))
result = self.fetch()
finally:
self.close()
return result
pass
def createUser(self,user):
try:
sql = "insert into ly_user(user_name,user_password,user_zsname,user_age,user_sex,user_phonenum,user_city,user_address) values(%s,%s,%s,%s,%s,%s,%s,%s)"
self.getConnection()
result = self.execute(sql,(user.userName,user.userPwd,user.zsUserName,user.ages,user.sex,user.telphone,user.city,user.xxdz))
self.commit() #执行语句后要提交
finally:
self.close()
return result
pass
#查询功能的函数
def findUserList(self,user):
try:
params = []
#sql语句和param就需要是动态
sql="select * from ly_user where 1=1 " # where 1=1 便于增加and
if user.userName:
sql += " and user_name like %s "
params.append('%'+user.userName+'%') #支持模糊查询
pass
if user.city:
sql += " and user_city=%s "
params.append(user.city)
pass
self.getConnection()
self.execute(sql,params)
result = self.fetch()
finally:
self.close()
return result
pass
#删除功能的函数
def removeUser(self,userId):
try:
sql = "delete from ly_user where user_id=%s"
self.getConnection()
result = self.execute(sql, (userId,))
self.commit() # 执行语句后要提交
finally:
self.close()
return result
pass
#修改数据库数据
def updateUser(self,user):
try:
sql = "update ly_user set user_name=%s,user_zsname=%s,user_age=%s,user_sex=%s,user_phonenum=%s,user_city=%s,user_address=%s where user_id=%s"
self.getConnection()
result = self.execute(sql,(user.userName,user.zsUserName,user.ages,user.sex,user.telphone,user.city,user.xxdz,user.userId))
self.commit() # 执行语句后要提交
finally:
self.close()
return result
pass
#支持查询分页
def findPageUserList(self, user, pageSize, currentPage):
try:
params = []
# sql语句和params就需要是动态
sql = "select * from ly_user where 1=1 " # where 1=1是为了便于增加and
if user.userName:
sql += " and user_name like %s " # 模糊查询
params.append('%' + user.userName + '%')
pass
if user.city:
sql += " and user_city=%s "
params.append(user.city)
pass
startRow = (currentPage - 1) * pageSize
sql += "limit %s, %s"
params.append(startRow)
params.append(pageSize)
self.getConnection()
self.execute(sql, params)
result = self.fetch()
finally:
self.close()
return result
pass
def countUsers(self, user):
params = []
# sql语句和params就需要是动态
sql = "select count(*) from ly_user where 1=1 " # where 1=1是为了便于增加and
if user.userName:
sql += " and user_name like %s " # 模糊查询
params.append('%' + user.userName + '%')
pass
if user.city:
sql += " and user_city=%s"
params.append(user.city)
pass
self.getConnection()
self.execute(sql, params)
result = self.fetchOne()
return result
pass
pass
user.py文件(初始化用户实体属性文件)
class User():
def __init__(self):
self.__userId = None
self.__userName=None
self.__userPwd = None
self.__reUserPwd =None
self.__zsUserName =None
self.__ages = None
self.__sex = None
self.__telphone=None
self.__city=None
self.__xxdz=None
@property
def userId(self):
return self.__userId
@userId.setter
def userId(self, userId):
self.__userId = userId
@property
def userName(self):
return self.__userName
@userName.setter
def userName(self,userName):
self.__userName = userName
@property
def userPwd(self):
return self.__userPwd
@userPwd.setter
def userPwd(self,userPwd):
self.__userPwd = userPwd
@property
def reUserPwd(self):
return self.__reUserPwd
@reUserPwd.setter
def reUserPwd(self, reUserPwd):
self.__reUserPwd = reUserPwd
@property
def zsUserName(self):
return self.__zsUserName
@zsUserName.setter
def zsUserName(self, zsUserName):
self.__zsUserName = zsUserName
@property
def ages(self):
return self.__ages
@ages.setter
def ages(self, ages):
self.__ages = ages
@property
def sex(self):
return self.__sex
@sex.setter
def sex(self, sex):
self.__sex = sex
@property
def telphone(self):
return self.__telphone
@telphone.setter
def telphone(self, telphone):
self.__telphone = telphone
@property
def city(self):
return self.__city
@city.setter
def city(self, city):
self.__city = city
@property
def xxdz(self):
return self.__xxdz
@xxdz.setter
def xxdz(self, xxdz):
self.__xxdz = xxdz
userservice.py文件
from dao.userdao import UserDao
from entity.user import User
class UserService():
def findUserByUserName(self,userName):
userDao = UserDao()
return userDao.findUserByUserName(userName)
pass
def createUser(self,user): #参数user是数据实体类
userDao = UserDao()
return userDao.createUser(user)
#将查询数据进行数据封装
def findUserList(self,user):
userDao = UserDao()
userList=[]
result = userDao.findUserList(user)
for temp in result:
user = User()
user.userId = temp[0]
user.userName = temp[1]
user.zsUserName = temp[3]
user.ages=temp[4]
user.sex=temp[5]
user.telphone=temp[6]
user.city = temp[7]
user.xxdz = temp[8]
userList.append(user)
return userList
pass
#删除 id
def removeUser(self,userId):
userDao = UserDao()
return userDao.removeUser(userId)
pass
#修改
def updateUser(self,user):
userDao = UserDao()
return userDao.updateUser(user) #对数据库进行更新操作
#分页
def findPageUserList(self, user, pageSize, currentPage):
userDao = UserDao()
return userDao.findPageUserList(user, pageSize, currentPage)
pass
#计算用户个数
def countUsers(self, user):
userDao = UserDao()
return userDao.countUsers(user)[0]
pass
formvalidator.js文件(未删减版,此文件中有宝藏可以挖掘,哈哈!)
function checkLoginForms(){
userName =document.getElementById('username').value
userPwd = document.getElementById('userpwd').value
if(userName=="" || userPwd==""){
document.getElementById('tswk').innerHTML='用户名和密码不能为空'
return false
}
return true
}
//用户注册界面的约束条件如下
function checkRegistForms() {
userName = document.getElementById('username').value
userPwd = document.getElementById('pword').value
reuserPwd = document.getElementById('repword').value
ages = document.getElementById('ages').value
sexx = document.getElementById('sexx').value
telphone=document.getElementById('telphone').value
city = document.getElementById('city').value
xxdz = document.getElementById('xxdz').value
//用DOM做提示信息
pattern = /^[a-zA-Z_]\w{5,17}$/
if (!pattern.test(userName)){
document.getElementById('yhts').innerHTML='用户名必须6-18位,必须使用字符和下划线开头'
return false
}
if(userPwd == "" || userPwd != reuserPwd){
document.getElementById('jymm').innerHTML = '两次输入密码不一致,请重新输入'
return false
}
pattern = /^\d{1,3}$/
if (!pattern.test(ages)){
document.getElementById('age').innerHTML = '请输入正整数'
return false
}
if(sexx!='男' && sexx!='女'){
document.getElementById('sexs').innerHTML = '请正确输入"男"或者"女"'
return false
}
pattern = /^\d{1,11}$/
if(!pattern.test(telphone)){
document.getElementById('phone').innerHTML = '请输入正确的联系方式'
return false
}
cityList=["河北省","山西省","辽宁省","吉林省","黑龙江省","江苏省","浙江省",
"安徽省","福建省","江西省","山东省","河南省","湖北省","湖南省","广东省","海南省",
"四川省","贵州省","云南省","陕西省","甘肃省","青海省","台湾省"]
if(cityList.indexOf(city)<0){
document.getElementById('citys').innerHTML='请输入"**省"即可'
return false
}
if(xxdz==""){
document.getElementById('address').innerHTML = '请填写正确地址信息,便于邮寄'
return false
}
return true //true 因为form有onsubmit="checkLoginForm()
}
//以上信息为注册信息验证操作,无伤大雅!
//删除
function submitRemoveUser(userId) {
if(confirm("确定要删除吗?")){
window.location.href="/removeuser.do?userId="+userId
}
}
//修改
function submitModifyUser(id) {
//console.log('#list-line' + id +" td")
// contentEditable为css3样式属性 设为 true可以选中当前网页中的表格,使其可以文本编辑
$('#list-line' + id +" td").attr('contentEditable',true);
}
//点击 完成 按钮的功能,动态将修改的数据传入控制层(usercontroller.py文件);
//而后对数据库进行更新操作,实现不切换界面就能对数据进行修改操作
function submitModifyUsers(id){
$.ajax({
type: 'post', // 传数据的方式
url: '/checkusername.do',
dataType: 'json', // xml、json、script、html
data:JSON.stringify({
'userId': $("td[name='userId"+id+"']").html(), // $('#userName') == document.getElementById('userName')
'userName': $("td[name='userName"+id+"']").html(),
'userzsname': $("td[name='userzsname"+id+"']").html(),
'userages': $("td[name='userages"+id+"']").html(),
'usersex': $("td[name='usersex"+id+"']").html(),
'usertelphone': $("td[name='usertelphone"+id+"']").html(),
'usercity': $("td[name='usercity"+id+"']").html(),
'userxxdz': $("td[name='userxxdz"+id+"']").html(),
}),
error: function(xhr, err){
alert('请求失败,请检查,' + err + '!')
},
success: function(data, textStatus){ // success对应的回调函数的第一个参数,是服务器返回的数据
if(data.code==1){
$('#list-line' + id +" td").attr('contentEditable',false)
alert("修改完成!")
}
}
});
}
//分页 opr事件分类
function getUserData(currentPage, pageSize, opr, userId) {
userName = document.searchForm.userName.value
userCity = document.searchForm.userCity.value
$.ajax({
type: 'post', // 传数据的方式
url: '/ajaxuserinfo.do',
dataType: 'json', // xml、json、script、html
data:JSON.stringify({
'userName':userName,
'userCity':userCity,
'userId': userId, 'pageSize': pageSize,
'currentPage': currentPage,
'opr': opr
}),
error: function(xhr, err){
alert('请求失败,请检查,' + err + '!')
},
success: function(data, textStatus){ // success对应的回调函数的第一个参数,是服务器返回的数据
var htmlText = ""
for(var i =0;i \n' +
' \n' +
' '+ data.userData[i][0] +' \n' +
' '+ data.userData[i][1] +' \n' +
' '+ data.userData[i][3] +' \n' +
' '+ data.userData[i][4] +' \n' +
' '+ data.userData[i][5] +' \n' +
' '+ data.userData[i][6] +' \n' +
' '+ data.userData[i][7] +' \n' +
' '+ data.userData[i][8] +' \n' +
' \n' +
' 删除 \n' +
' 修改 \n' +
' 完成\n' +
' \n' +
' \n' +
'\n' +
' '
}
pageText = '--------------------------------------------------------------------------------------------------- ' +
''+ '当前第' + data.currentPage + '页 总共有' + data.totalPage + '页 ';
if(data.currentPage <= 1) {
pageText += '首页 上一页 ';
}else{
pageText += '首页 ' +
'上一页 ';
}
if(data.currentPage >= data.totalPage){
pageText += '下一页 尾页 ';
}else {
pageText += '下一页 ' +
'尾页 ';
}
pageText +=' '
$('#dataBody').empty()
$('#dataBody').append(htmlText)
$('#dataBody').append(pageText)
document.searchForm.currentPage.value = data.currentPage
document.searchForm.pageSize.value=data.pageSize
}});}$(document).ready(function(){getUserData(1, 16, 'search', 0)
})
messageinfo.html文件(管理员界面,利用了bootstrap3框架样式,可为读者做参考使用,未删减版)
后台管理界面
管理员界面
ID
用户名
真实姓名
年龄
性别
手机号
籍贯
详细地址
操作
{# {% for user in userList %}#}
{# #}
{# #}
{# {{ user.userId }} #}
{# {{ user.userName }} #}
{# {{ user.zsUserName }} #}
{# {{ user.ages }} #}
{# {{ user.sex }} #}
{# {{ user.telphone }} #}
{# {{ user.city }} #}
{# {{ user.xxdz }} #}
{# #}
{# 删除 #}
{# 修改 #}
{# 完成#}
{# #}
{# #}
{# {% endfor %}#}
商品管理界面尚未开发
订单界面暂未开发
销量界面暂未开发
app.py文件(启动程序)
from flask import Flask,render_template,request,session,Response
from controller.usercontroller import usercontroller
from datetime import timedelta
app = Flask(__name__)
app.config['DEBUG']=True
app.config['SECRET_KEY'] ="fggggjjjhgggg"
app.config['PERMANENT_SESSION_LIFETIME']=timedelta(minutes=30)
app.register_blueprint(usercontroller)
@app.route('/',methods =['POST','GET'])
def index():
return render_template('systeminfo/messageinfo.html')
if __name__ == '__main__':
app.run()