背景:
使用flask开发的一个web系统,后台用户管理采用的是点击目录后采用load方式不刷新动态加载
1、如图,点击“兖矿集团”,动态加载出右侧的页面
主页面html名称:usermanage.html,代码如下:
{% extends 'base.html' %}
{% block headload %}
<!-- Bootstrap-table css -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/bootstrap-table.css') }}">
{% endblock headload %}
{% block sidebarfunction2 %}
{% endblock sidebarfunction2 %}
{% block sidebarfunction6 %}
{% endblock sidebarfunction6 %}
{% block sidebarfunction7 %}
{% endblock sidebarfunction7 %}
{% block sidebarfunction3 %}
{% endblock sidebarfunction3 %}
{% block sidebarfunction4 %}
<li class="active treeview">
<a href="#">
<i class="fa fa-gear"></i> <span>系统管理</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li class="active"><a href="{{ url_for('usermanage') }}"><i class="fa fa-user"></i> 用户管理</a></li>
<li><a href="{{ url_for('initialize') }}"><i class="fa fa-hourglass-2"></i> 系统初始化</a></li>
</ul>
</li>
{% endblock sidebarfunction4 %}
{% block contentheader1 %}
<h1>用户管理</h1>
{% endblock contentheader1 %}
{% block contentheader2 %}
<li> 系统管理</li>
<li class="active">用户管理</li>
{% endblock contentheader2 %}
{% block content %}
<section class="content">
<!-- 添加custom tab -->
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom with-border">
<ul class="nav nav-tabs">
<li class="active"><a href="#user" data-toggle="tab">普通用户</a></li>
<li><a href="#admin" data-toggle="tab">管理员</a></li>
</ul>
<div class="tab-content">
<!--普通用户-->
<div class="tab-pane active" id="user">
<div class="row">
<div class="col-xs-3"> <!-- 设备树区域 -->
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">组织结构</h3>
</div>
<div class="box-body">
<div id="treeview-user" class=""></div>
</div>
</div>
</div>
<div class="col-xs-9"> <!-- 数据区域 -->
<div id="generaluser">
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">普通用户添加</h3>
</div>
<!-- /.box-header -->
<div class="box-body" id="datashow-adduser">
<div class="alert alert-info alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×
</button>
<h4><i class="icon fa fa-info"></i> 提示信息!</h4>
请点击左侧组织结构节点进行操作!
</div>
</div>
<!-- /.box-body -->
</div>
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">普通用户删除</h3>
</div>
<!-- /.box-header -->
<div class="box-body" id="datashow-deluser">
<div class="alert alert-info alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×
</button>
<h4><i class="icon fa fa-info"></i> 提示信息!</h4>
请点击左侧组织结构节点进行操作!
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</div>
</div>
<!--管理员-->
<div class="tab-pane" id="admin">
<div class="row">
<div class="col-xs-3"> <!-- 设备树区域 -->
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">组织结构</h3>
</div>
<div class="box-body">
<div id="treeview-admin" class=""></div>
</div>
</div>
</div>
<div class="col-xs-9"> <!-- 数据区域 -->
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">管理员添加</h3>
</div>
<!-- /.box-header -->
<div class="box-body" id="datashow-addadmin">
<div class="alert alert-info alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×
</button>
<h4><i class="icon fa fa-info"></i> 提示信息!</h4>
请在左侧设备树选择最终测点!
</div>
</div>
<!-- /.box-body -->
</div>
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">管理员删除</h3>
</div>
<!-- /.box-header -->
<div class="box-body" id="datashow-deladmin">
<div class="alert alert-info alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×
</button>
<h4><i class="icon fa fa-info"></i> 提示信息!</h4>
请在左侧设备树选择最终测点!
</div>
</div>
<!-- /.box-body -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock content %}
{% block script %}
{{ super() }}
<!-- Bootstrap Tree View js -->
<script src="{{ url_for('static', filename='admin/bootstrap-treeview.js') }}"></script>
<script src="{{ url_for('static', filename='admin/bootstrap-table.js') }}"></script>
<script type="text/javascript">
$(function () {
var tempdata = {{ groups | tojson }};
var groups = JSON.parse(tempdata);
$('#treeview-user').treeview({
levels: 1,
color: "#428bca",
showTags: true,
enableLinks: true,
selectable: true,
data: groups,
onNodeSelected: function (event, node) {
// $('div#datashow-adduser').load(url = "{{ url_for('index') }}" + 'system/usermanage_ajax/' + node.id + '/' + node.gid + '/' + node.cid + '/' + node.ccid + '/' + node.mid + '/' + node.ssid + ' #adduser'); //注意#号前的空格
// $('div#datashow-deluser').load(url = "{{ url_for('index') }}" + 'system/usermanage_ajax/' + node.id + '/' + node.gid + '/' + node.cid + '/' + node.ccid + '/' + node.mid + '/' + node.ssid + ' #deluser');
$('div#generaluser').load(url = "{{ url_for('index') }}" + 'system/usermanage_ajax/' + node.id + '/' + node.gid + '/' + node.cid + '/' + node.ccid + '/' + node.mid + '/' + node.ssid);
}
});
});
function changepass() {
window.open("{{ url_for('index') }}" + 'system/usermanage/changepass');
// window.open("http://133dg.com");
}
</script>
{% endblock script %}
对应的视图函数:
@app.route('/system/usermanage/')
@login_required
def usermanage():
current_time = datetime.utcnow()
groups = general.Groups()
return render_template('system/usermanage.html', groups=json.dumps(groups), current_time=current_time)
加载的右侧页面名称:usermanage_ajax.html,代码如下:
<!DOCTYPE html>
<!-- Bootstrap-table css -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/bootstrap-table.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='admin/bower_components/bootstrap/dist/css/bootstrap.min.css') }}">
<!-- Font Awesome -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/bower_components/font-awesome/css/font-awesome.min.css') }}">
<!-- Ionicons -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/bower_components/Ionicons/css/ionicons.min.css') }}">
<!-- jvectormap -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/bower_components/jvectormap/jquery-jvectormap.css') }}">
<!-- Theme style -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/dist/css/AdminLTE.min.css') }}">
<!-- AdminLTE Skins. Choose a skin from the css/skins
folder instead of downloading all of them to reduce the load. -->
<link rel="stylesheet" href="{{ url_for('static', filename='admin/dist/css/skins/_all-skins.min.css') }}">
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">普通用户添加</h3>
</div>
<div class="box-body" id="adduser">
<h4>当前添加用户权限范围:<span class="text-primary text-bold"> {{ info.name }} </span></h4>
<br />
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ message }}
</div>
{% endfor %}
<form class="form" method="post" id="adduserform">
{{ form.csrf_token() }}
<div class="row">
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-user fa-fw fa-lg"></i></span>
{{ form.username(class="form-control", placeholder="用户名") }}
<!--<input type="text" class="form-control" placeholder="用户名" name="username">-->
</div>
<span style="color: red;" id="username"></span>
</div>
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-lock fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="密码" name="password">-->
{{ form.password(class="form-control", placeholder="密码") }}
</div>
<span style="color: red;" id="password"></span>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-vcard fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="姓名" name="name">-->
{{ form.name(class="form-control", placeholder="姓名") }}
</div>
<span style="color: red;" id="name"></span>
</div>
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-male fa-fw fa-lg"></i></span>
<!--<select class="form-control" name="sex">-->
<!--<option>男</option>-->
<!--<option>女</option>-->
<!--</select>-->
{{ form.sex(class="form-control") }}
<span class="input-group-addon"><i class="fa fa-female fa-fw fa-lg"></i></span>
</div>
<span style="color: red;" id="sex"></span>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-mobile fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="手机" name="mobile">-->
{{ form.mobile(class="form-control", placeholder="手机") }}
</div>
<span style="color: red;" id="mobile"></span>
</div>
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-envelope fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="邮箱" name="email">-->
{{ form.email(class="form-control", placeholder="邮箱") }}<label>{{ form.email.errors[0] }}</label>
</div>
<span style="color: red;" id="email"></span>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-users fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="头衔" name="title">-->
{{ form.title(class="form-control", placeholder="职衔") }}
</div>
<span style="color: red;" id="title"></span>
</div>
<div class="col-lg-6">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-phone fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="座机" name="telephone">-->
{{ form.telephone(class="form-control", placeholder="座机") }}
</div>
<span style="color: red;" id="telephone"></span>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-12">
<div class="input-group has-feedback">
<span class="input-group-addon"><i class="fa fa-address-book fa-fw fa-lg"></i></span>
<!--<input type="text" class="form-control" placeholder="地址" name="address">-->
{{ form.address(class="form-control", placeholder="地址") }}
</div>
<span style="color: red;" id="address"></span>
</div>
</div>
<br />
<div class="row">
<div class="col-xs-12">
<!--<button type="submit" class="btn btn-primary btn-block" id="btn" onclick="test()"><i class="fa fa-user-plus fa-fw fa-lg" ></i> 添加用户</button>-->
{{ form.submit(class="btn btn-primary btn-block", id="btn") }}
</div>
</div>
</form>
</div>
</div>
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">普通用户管理</h3>
</div>
<div class="box-body" id="deluser">
<h4>权限范围为{{ info.name }}的已有用户列表:</h4>
<br />
<table id="table" data-toggle="table" class="table table-hover table-bordered">
<thead>
<tr>
<th class="text-center">序号</th>
<th class="text-center">用户名</th>
<th class="text-center">姓名</th>
<th class="text-center">职衔</th>
<th class="text-center">性别</th>
<th class="text-center">手机号</th>
<th class="text-center">邮箱</th>
<th class="text-center">座机</th>
<th class="text-center">地址</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
{% for i in user_list %}
<tr>
<td class="text-center">{{ loop.index }}</td>
<td class="text-center">{{ i.username }}</td>
<td class="text-center">{{ i.name }}</td>
<td class="text-center">{{ i.title }}</td>
<td class="text-center">{{ i.sex }}</td>
<td class="text-center">{{ i.mobile }}</td>
<td class="text-center">{{ i.email }}</td>
<td class="text-center">{{ i.telephone }}</td>
<td class="text-center">{{ i.address }}</td>
<td class="text-center">
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#modal1" data-username="{{ i.username }}" style="margin-right:15px;"><i class="fa fa-refresh" ></i> 重置密码</button>
<button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#modal2" data-username="{{ i.username }}" ><i class="fa fa-trash" ></i> 删除用户</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!--重置密码模态框-->
<div class="modal modal-warning fade" id="modal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title">重置密码</h4>
</div>
<div class="modal-body">
<p>确认重置用户:<span id="username1" class="label-primary"></span> 的密码?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">取消</button>
<button type="button" id="confirm1" onclick="" class="btn btn-outline">确认重置密码</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!--删除用户模态框-->
<div class="modal modal-danger fade" id="modal2">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title">删除用户</h4>
</div>
<div class="modal-body">
<p>确认删除用户:<span id="username2" class="label-primary"></span> ?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">取消</button>
<button type="button" id="confirm2" onclick="" class="btn btn-outline">确认删除用户</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
</div>
</div>
<script type="text/javascript">
$('#modal1').on('show.bs.modal', function (e) {
//get data-id attribute of the clicked element
var username = $(e.relatedTarget).data('username');
// alert(username);
//populate the textbox
$(e.currentTarget).find('span#username1').text(username);
$(e.currentTarget).find('button#confirm1').attr("onclick", "location.href='{{ url_for('index') }}' + 'system/usermanage/resetpass/" + username + "'" + ";return false;")
});
$('#modal2').on('show.bs.modal', function (e) {
//get data-id attribute of the clicked element
var username = $(e.relatedTarget).data('username');
// alert(username);
//populate the textbox
$(e.currentTarget).find('span#username2').text(username);
$(e.currentTarget).find('button#confirm2').attr("onclick", "location.href='{{ url_for('index') }}' + 'system/usermanage/deluser/" + username + "'" + ";return false;")
});
$(function () {
$('#btn').click(function () {
//ajax提交
post_data = $('#adduserform').serialize();
function show (data, tag) {
if (data.errors.hasOwnProperty(tag)) {
$('span#'+tag).text(data.errors[tag])
// alert(data.errors['username'])
}
else {
$('span#'+tag).text('')
}
}
$.ajax({
url: "{{ url_for('adduser', gid=info.gid, cid=info.cid, ccid=info.ccid, mid=info.mid, ssid=info.ssid) }}",
type: 'POST',
data: post_data,
success: function (data) {
show(data, 'username');
show(data, 'password');
show(data, 'name');
show(data, 'sex');
show(data,'mobile');
show(data,'email');
show(data,'title');
show(data,'telephone');
show(data,'address');
}
});
});
});
function test() {
//ajax提交
post_data = $('#adduserform').serialize();
function show (data, tag) {
if (data.errors.hasOwnProperty(tag)) {
$('span#'+tag).text(data.errors[tag])
// alert(data.errors['username'])
}
else {
$('span#'+tag).text('')
}
}
$.ajax({
url: "{{ url_for('adduser', gid=info.gid, cid=info.cid, ccid=info.ccid, mid=info.mid, ssid=info.ssid) }}",
type: 'POST',
data: post_data,
success: function (data) {
show(data, 'username');
show(data, 'password');
show(data, 'name');
show(data, 'sex');
show(data,'mobile');
show(data,'email');
show(data,'title');
show(data,'telephone');
show(data,'address');
}
});
}
</script>
对应的视图函数:
@app.route('/system/usermanage_ajax/<id>/<gid>/<cid>/<ccid>/<mid>/<ssid>')
@login_required
def usermanage_ajax(id, gid, cid, ccid, mid, ssid):
current_time = datetime.utcnow()
info = {}
user_list = []
adduserform = general.AddUserForm()
sql1 = '''select u.gid,u.cid,u.ccid,u.mid,u.ssid,u.username
from users u
where (u.gid={0} or {0} is null)
and (u.cid={1} or {1} is null)
and (u.ccid={2} or {2} is null)
and (u.mid={3} or {3} is null)
and (u.ssid={4} or {4} is null)'''.format(gid, cid, ccid, mid, ssid)
users = general.SQL(sql1)
sql2 = '''select i.groupname,i.companyname1,i.companyname2,i.minename,'该套设备'
from identifier i
where (i.gid={0} or {0} is null)
and (i.cid={1} or {1} is null)
and (i.ccid={2} or {2} is null)
and (i.mid={3} or {3} is null)
and (i.ssid={4} or {4} is null)'''.format(gid, cid, ccid, mid, ssid)
temp = general.SQL(sql2)[0]
info['gid'] = gid
info['cid'] = cid
info['ccid'] = ccid
info['mid'] = mid
info['ssid'] = ssid
if int(id) < 10000:
for user in users:
if not user['cid']:
user_list.append(user)
info['name'] = temp['groupname']
elif 10000 < int(id) < 20000:
for user in users:
if not user['ccid'] and not user['mid']:
user_list.append(user)
info['name'] = temp['groupname'] + '>>' + temp['companyname1']
elif 20000 < int(id) < 30000:
for user in users:
if not user['mid']:
user_list.append(user)
info['name'] = temp['groupname'] + '>>' + temp['companyname1'] + '>>' + temp['companyname2']
elif 30000 < int(id) < 40000:
for user in users:
if not user['ssid']:
user_list.append(user)
if not temp['companyname2']:
info['name'] = temp['groupname'] + '>>' + temp['companyname1'] + '>>' + temp['minename']
else:
info['name'] = temp['groupname'] + '>>' + temp['companyname1'] + '>>' + temp['companyname2'] + '>>' + temp['minename']
elif len(id) == 7:
if not temp['companyname2']:
info['name'] = temp['groupname'] + '>>' + temp['companyname1'] + '>>' + temp['minename'] + '>>' + '该套设备'
else:
info['name'] = temp['groupname'] + '>>' + temp['companyname1'] + '>>' + temp['companyname2'] + '>>' + temp['minename'] + '>>' + '该套设备'
return render_template('system/usermanage_ajax.html', current_time=current_time, info=info, user_list=user_list, form=adduserform)
2、问题
为了实现添加用户表单(adduserform)的表单验证,我使用了wtform,效果如图
这个表单的代码:
class AddUserForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired(message='用户名不能为空')])
password = StringField('密码', validators=[DataRequired('用户密码不能为空!'), Length(min=4, message='密码位数要大于4位')])
name = StringField('姓名', validators=[DataRequired('用户姓名不能为空!')])
sex = SelectField(choices=[(1, '男'), (2, '女')], coerce=int)
mobile = StringField('手机', validators=[DataRequired('用户手机不能为空!')])
def validate_mobile(form, field):
if not field.data.isnumeric():
raise StopValidation('手机号只能输入数字')
elif len(str(field.data)) != 11:
raise StopValidation('手机号位数不正确')
email = StringField('邮箱', validators=[DataRequired('用户邮箱不能为空!'), Email('邮箱格式错误!')])
title = StringField('职衔', validators=[DataRequired('用户职衔不能为空!')])
telephone = StringField('座机', validators=[DataRequired('用户座机不能为空!')])
address = StringField('地址', validators=[DataRequired('用户地址不能为空!')])
submit = SubmitField('登录')
adduser视图函数:
@app.route('/system/usermanage/adduser/<gid>/<cid>/<ccid>/<mid>/<ssid>', methods=['POST'])
@login_required
def adduser(gid, cid, ccid, mid, ssid):
adduserform = general.AddUserForm(request.form)
info = {}
info['gid'] = gid
info['cid'] = cid
info['ccid'] = ccid
info['mid'] = mid
info['ssid'] = ssid
print(adduserform.validate())
if request.method == 'POST':
if adduserform.validate_on_submit():
formdatas = request.form
print('formdatas',formdatas)
password = generate_password_hash(formdatas['password'])
username = formdatas['username'].strip()
if general.SQL('''select username from users where username='{0}' '''.format(username)):
info['type'] = 'warning'
info['title'] = '错误'
info['notice'] = '用户名:' + username + ' 已存在!'
print('用户名:' + username + ' 已存在!')
return render_template('notice.html', info=info)
# flash('用户名:' + username + ' 已存在!')
# errors['flash'] = '用户名:' + username + ' 已存在!'
else:
sql = '''insert into users (gid,cid,ccid,mid,ssid,username,password,type,name,sex,email,mobile,telephone,title,address)
values ({0},{1},{2},{3},{4},'{5}','{6}',{7},'{8}','{9}','{10}','{11}','{12}','{13}','{14}')'''.format(
gid,cid,ccid,mid,ssid,username,password,3,formdatas['name'],formdatas['sex'],formdatas['email'],
formdatas['mobile'],formdatas['title'],formdatas['telephone'],formdatas['address'])
print(sql)
try:
general.SQL(sql)
info['type'] = 'success'
info['title'] = '添加用户成功'
info['notice'] = '用户' + username + ' 已添加!'
print('返回失败?')
return render_template('notice.html', info=info)
except Exception as error:
print(request.path, error)
info['type'] = 'warning'
info['title'] = '错误'
info['notice'] = '出现错误,请联系管理员!'
return render_template('notice.html', info=info)
else:
errors = adduserform.get_errors()
print(errors)
return jsonify({'status':400, 'errors': errors})
else:
pass
为了能在当前页面显示验证的错误信息,在usermanage_ajax.html页面,我使用了ajax,采用post方式提交到adduser视图处理,那么问题来了,本来程序执行到这个地方:
try:
general.SQL(sql)
info['type'] = 'success'
info['title'] = '添加用户成功'
info['notice'] = '用户' + username + ' 已添加!'
print('返回失败?')
return render_template('notice.html', info=info) #执行到这个地方返回了视图
except Exception as error:
print(request.path, error)
info['type'] = 'warning'
info['title'] = '错误'
info['notice'] = '出现错误,请联系管理员!'
return render_template('notice.html', info=info)
应该返回结果的,类似下图的效果
但是,实际上却出现如下的错误:
我大概了解是因为从system/usermanage发起的请求,referer指向的是system/usermanage,所以返回到此,但是因为system/usermanage的视图函数我并没有设置POST方法,所以报了这个错误,我想问的是该怎么处理这个? 以使他能达到我需要的效果(显示notice.html视图,也就是哪个类似的效果)
3、我试过的方法
如果在usermanage_ajax.html中不采用ajax方式post,而是将url写到form的action里,程序执行到这个地方是不会报错的,但是不采用ajax貌似不能在当前页显示验证的错误消息啊
try:
general.SQL(sql)
info['type'] = 'success'
info['title'] = '添加用户成功'
info['notice'] = '用户' + username + ' 已添加!'
print('返回失败?')
return render_template('notice.html', info=info) #执行到这个地方返回了视图
except Exception as error:
print(request.path, error)
info['type'] = 'warning'
info['title'] = '错误'
info['notice'] = '出现错误,请联系管理员!'
return render_template('notice.html', info=info)
4、拜托各位大神帮帮忙,这个问题卡了我3天了,非常感谢。半路出家的程序猿,水平比较渣
总结一下,不要让他出现405错误,能正常返回我的notice视图
5、P.S. 还有一个问题,就是wtforms的验证即使出现了错误,为什么还是能通过提交,难道不是应该停下来等待修正输入吗?
如果是空的,页面不会提交,但是比如邮箱,虽然填了,但是格式不正确,或者手机,位数不正确(我后台已经抓取到了错误),但是页面为什么还是会提交呢?(然后就会显示那个405错误)
是我的问题描述的不够详细吗? 怎么没有过路大侠给解答下?