zoukankan      html  css  js  c++  java
  • 类似库联合查询系统

     源码地址:https://github.com/FFlask/search_db

    1、需求分析

    N个数据库,依次模糊查询后返回结果,汇总后展示到界面上

    数据库是保存在本地数据库中,并在后台界面动态的添加到查询系统中

    为了保证安全,加个登陆,但不开放注册,统一在后台界面添加新用户

    用户分为管理员和普通用户,管理员可以添加普通用户

    单一IP暴力破解登陆的问题使用Nginx+验证码(暂未实现)来解决

    2、数据库设计

    共需要三张表,用户表和权限表,数据库管理表(用于保存需要查询的数据库)

    3、框架选择

    由于最近在学习Flask框架,本项目采用Flask框架和其配套模块

    前端使用Bootstrap框架

    由于功能简单(代码500行内),就所有代码就写在一个文件上了

    4、具体功能实现

    4.1 实现说明

    已实现功能:登陆,汇总查询,数据表的增删改查,权限控制,普通用户的增删改查

    未实现功能:验证码

    系统的难点:数据表和本地数据库表的动态关联,使用了元类,通过字符串找类,动态创建变量名

    初始化:初始化创建表的时候应将元类创建模型的部分注释掉

    4.2 代码实现

      1 # -*- coding: UTF-8 -*-
      2 from flask import Flask,render_template,url_for,redirect,request,flash,session,abort
      3 from flask_sqlalchemy import SQLAlchemy
      4 from flask_wtf import FlaskForm
      5 from wtforms import StringField,PasswordField,SubmitField,SelectField,ValidationError
      6 from wtforms.validators import Email,EqualTo,Length,DataRequired
      7 from werkzeug.security import generate_password_hash,check_password_hash
      8 from flask_login import LoginManager,UserMixin,login_required,login_user,logout_user,current_user
      9 from functools import wraps
     10 
     11 
     12 app = Flask(__name__)
     13 login_manager = LoginManager()
     14 #设置验证强度,以提供不同的安全等级防止用户会话遭篡改
     15 #设为'strong' 时,Flask-Login 会记录客户端IP地址和浏览器的用户代理信息,如果发现异动就登出用户
     16 login_manager.session_protection = 'strong'
     17 #设置登陆失败后的跳转
     18 login_manager.login_view = 'index'
     19 
     20 
     21 class Config:
     22     SECRET_KEY = '1a1@z2'
     23     SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@127.0.0.1/world?charset=utf8'
     24 
     25     #SQLALCHEMY_TRACK_MODIFICATIONS = True
     26     @staticmethod
     27     def init_app(app):
     28         pass
     29 
     30 app.config.from_object(Config)
     31 db=SQLAlchemy(app)
     32 
     33 #数据库模型
     34 
     35 @login_manager.user_loader
     36 def load_user(user_id):
     37     return User.query.get(int(user_id))
     38 login_manager.init_app(app)
     39 #用户表
     40 class User(UserMixin,db.Model):
     41     __tablename__ = 'user'
     42     id = db.Column(db.Integer,primary_key=True,index=True)
     43     username = db.Column(db.String(64),unique=True,index=True)
     44     password_hash = db.Column(db.String(128))
     45     role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
     46 
     47     @property
     48     def password(self):
     49         raise AttributeError('password unread')
     50 
     51     @password.setter
     52     def password(self,password):
     53         self.password_hash = generate_password_hash(password)
     54 
     55     def verify_password(self,password):
     56         return check_password_hash(self.password_hash,password)
     57 
     58     #新增用户默认是普通用户权限
     59     def __init__(self,*args,**kwargs):
     60         super(User,self).__init__(*args,**kwargs)
     61         if self.role is None:
     62             if self.username == 'admin':
     63                 self.role = Role.query.filter_by(role_name='Admin').first()
     64             else:
     65                 self.role = Role.query.filter_by(role_name='User').first()
     66 
     67     def can(self,permissions):
     68         return self.role is not None and (self.role.permissions & permissions) == permissions
     69 
     70     def is_admin(self):
     71         return self.can(Permissions.Admin)
     72 
     73     def __repr__(self):
     74         return '<User %r>'%(self.username)
     75 
     76 
     77 #权限类
     78 class Permissions:
     79     Visit = 0x01
     80     Read = 0x02
     81     Write = 0x04
     82     Manager = 0x08
     83     Admin = 0xFF
     84 
     85 #角色权限表
     86 class Role(db.Model):
     87     __tablename__ = 'role'
     88     id = db.Column(db.Integer,primary_key=True,index=True)
     89     role_name = db.Column(db.String(64),unique=True,index=True)
     90     permissions = db.Column(db.Integer)
     91     user = db.relationship('User',backref='role')
     92 
     93     @staticmethod
     94     def init_role():
     95         roles = {
     96             'Visitor':Permissions.Visit,
     97             'User':Permissions.Visit|Permissions.Read|Permissions.Write,
     98             'Manager':Permissions.Visit|Permissions.Read|Permissions.Write|Permissions.Manager,
     99             'Admin':Permissions.Admin
    100         }
    101         for role_name,role_permissions in roles.items():
    102             role = Role(role_name=role_name,permissions=role_permissions)
    103             db.session.add(role)
    104             db.session.commit()
    105 
    106     def __repr__(self):
    107         return '<Role %r>'%(self.role_name)
    108 
    109 
    110 
    111 #数据库表
    112 class DBTable(db.Model):
    113     __tablename__ = 'db_table'
    114     id = db.Column(db.Integer, primary_key=True, index=True)
    115     table_name = db.Column(db.String(64), unique=True)
    116     table_src = db.Column(db.String(64))
    117     def __repr__(self):
    118         return 'db_table <%r>'%(self.table_name)
    119 
    120 
    121 
    122 #动态创建数据库模型
    123 table1s = DBTable.query.all()
    124 #把字符串变成变量
    125 createVar = locals()
    126 for table1 in table1s:
    127     #使用元类动态创建表中存储的表名
    128     createVar[str(table1.table_name)] = type(str(table1.table_name),(db.Model,),{
    129         '__tablename__':table1.table_name,
    130         'id':db.Column(db.Integer, primary_key=True, index=True),
    131         'username':db.Column(db.String(64), unique=True,index=True),
    132         'password':db.Column(db.String(64)),
    133         'email':db.Column(db.String(64), unique=True,index=True),
    134         })
    135 
    136 
    137 #表单类
    138 #搜索框
    139 class SearchForm(FlaskForm):
    140     search = StringField(validators=[DataRequired()],
    141                          render_kw={'class':'form-control',
    142                                     'size':'50',
    143                                     'placeholder':'input search content'})
    144     kind = SelectField(choices=[
    145         ('username','username'),('email','email')
    146     ],render_kw={'class':'form-control'})
    147     submmit = SubmitField('Search',render_kw={'class':'btn btn-info'})
    148 
    149 #登陆框
    150 class LoginForm(FlaskForm):
    151     username = StringField('Username', validators=[DataRequired(), Length(1, 64)],
    152                            render_kw={'class':'form-control','placeholder':'enter your username'})
    153     password = PasswordField('Password', validators=[DataRequired()],
    154                              render_kw={'class':'form-control','placeholder':'enter your password'})
    155     verify_code = StringField('CheckCode',
    156                               render_kw={'class': 'form-control', 'placeholder': 'zzzzzzzzz'})
    157     submmit = SubmitField('Login',render_kw={'class':'btn btn-info'})
    158 
    159 #新增数据库
    160 class DBAddForm(FlaskForm):
    161     table_name = StringField('table_name', validators=[DataRequired()],
    162                            render_kw={'class':'form-control','placeholder':'table_name'})
    163     table_src = StringField('table_src', validators=[DataRequired()],
    164                               render_kw={'class': 'form-control', 'placeholder': 'table_src'})
    165     submmit = SubmitField('Add',render_kw={'class':'btn btn-info'})
    166 
    167 #编辑数据库
    168 class DBEditForm(FlaskForm):
    169     table_name = StringField('table_name', validators=[DataRequired()],
    170                            render_kw={'class':'form-control','placeholder':'table_name'})
    171     table_src = StringField('table_src', validators=[DataRequired()],
    172                               render_kw={'class': 'form-control', 'placeholder': 'table_src'})
    173     submmit = SubmitField('Edit',render_kw={'class':'btn btn-info'})
    174 
    175 #新增用户
    176 class UserAddForm(FlaskForm):
    177     username = StringField('username', validators=[DataRequired()],
    178                            render_kw={'class':'form-control','placeholder':'username'})
    179     password = StringField('password', validators=[DataRequired()],
    180                               render_kw={'class': 'form-control', 'placeholder': 'password'})
    181     submmit = SubmitField('Add',render_kw={'class':'btn btn-info'})
    182 
    183     def validate_username(self,field):
    184         if User.query.filter_by(username = field.data).first():
    185             raise ValidationError('username is repeat')
    186 
    187 #修改用户信息
    188 class UserEditForm(FlaskForm):
    189     username = StringField('username', validators=[DataRequired()],
    190                            render_kw={'class':'form-control','readonly':'readonly'})
    191     new_password = StringField('new_password',
    192                               render_kw={'class': 'form-control', 'placeholder': 'new password'})
    193     role = SelectField(coerce=int,render_kw={'class':'form-control'})
    194     submmit = SubmitField('Edit',render_kw={'class':'btn btn-info'})
    195     def __init__(self,*args,**kwargs):
    196         super(UserEditForm,self).__init__(*args,**kwargs)
    197         self.role.choices = [(role.id,role.role_name) for role in Role.query.order_by(Role.role_name).all()
    198                              if role.role_name=='Admin' or role.role_name == 'User']
    199 
    200 #权限控制装饰器
    201 def permission_required(permission):
    202     def decorator(func):
    203         @wraps(func)
    204         def decorated_function(*args, **kwargs):
    205             if not current_user.can(permission):
    206                 abort(403)
    207             return func(*args, **kwargs)
    208         return decorated_function
    209     return decorator
    210 #具有admin权限
    211 def is_admin(func):
    212     return permission_required(Permissions.Admin)(func)
    213 
    214 
    215 
    216 #业务逻辑
    217 #初次运行时运行一下,创建admin账户
    218 @app.route('/create_user')
    219 def create_user():
    220     user1 = User.query.filter_by(username = 'admin').first()
    221     if not user1:
    222         user2 = User(username='admin',password='admin')
    223         db.session.add(user2)
    224         db.session.commit()
    225     return 'ok'
    226 
    227 #测试
    228 @app.route('/test')
    229 def test():
    230     return 'test'
    231 
    232 #登陆页面
    233 @app.route('/',methods=['GET','POST'])
    234 def index():
    235     login_form = LoginForm()
    236     if current_user.is_authenticated:
    237         print(current_user.username)
    238     if login_form.validate_on_submit():
    239         user1 = User.query.filter_by(username = login_form.username.data).first()
    240         if user1 and user1.verify_password(login_form.password.data):
    241             login_user(user1)
    242             return redirect(request.args.get('next') or url_for('search_db'))
    243         else:
    244             flash('username or password error')
    245             return redirect(url_for('index'))
    246     return render_template('index.html',login_form=login_form)
    247 
    248 @app.route('/logout')
    249 @login_required
    250 def logout():
    251     logout_user()
    252     return redirect(url_for('index'))
    253 
    254 #搜索页面
    255 @app.route('/search_db',methods=['GET','POST'])
    256 @login_required
    257 def search_db():
    258     search_form = SearchForm()
    259     ip = request.remote_addr
    260     results = {}
    261     if search_form.validate_on_submit():
    262         search_item = search_form.kind.data
    263         for index,table1 in enumerate(DBTable.query.all()):
    264             try:
    265                 #动态创建变量名
    266                 createVar[str(table1.table_name)+str(index)] =
    267                     globals()[table1.table_name].query.filter(getattr(globals()[table1.table_name],search_item)
    268                                                               .like('%'+'%s'%search_form.search.data+'%')).all()
    269                 if createVar[str(table1.table_name)+str(index)] is not None:
    270                     results.update({table1.table_src: createVar[str(table1.table_name)+str(index)]})
    271             except:
    272                 flash('Your db is not have table <%s>,Please update it!'%(str(table1.table_name)))
    273     return render_template('search_db.html',search_form=search_form,results=results,ip=ip)
    274 
    275 #数据库管理/查
    276 @app.route('/admin_db/query')
    277 @login_required
    278 @is_admin
    279 def admin_db_query():
    280     return render_template('admin_db_query.html', table1s = DBTable.query.all())
    281 
    282 #数据库管理/增
    283 @app.route('/admin_db/add',methods=['POST','GET'])
    284 @login_required
    285 @is_admin
    286 def admin_db_add():
    287     db_add_form = DBAddForm()
    288     if db_add_form.validate_on_submit():
    289         new_table = DBTable(
    290             table_name=db_add_form.table_name.data,
    291             table_src=db_add_form.table_src.data,
    292         )
    293         db.session.add(new_table)
    294         db.session.commit()
    295         return redirect(url_for('admin_db_query'))
    296     return render_template('admin_db_add.html',db_add_form=db_add_form)
    297 
    298 #数据库管理/改
    299 @app.route('/admin_db/edit',methods=['POST','GET'])
    300 @login_required
    301 @is_admin
    302 def admin_db_edit():
    303     edit_id = request.args.get('edit_id')
    304     db_table1 = DBTable.query.filter_by(id=edit_id).first()
    305     db_edit_form = DBEditForm()
    306     if db_edit_form.validate_on_submit():
    307         db_table1.table_name = db_edit_form.table_name.data
    308         db_table1.table_src = db_edit_form.table_src.data
    309         db.session.add(db_table1)
    310         db.session.commit()
    311         return redirect(url_for('admin_db_query'))
    312     db_edit_form.table_name.data = db_table1.table_name
    313     db_edit_form.table_src.data = db_table1.table_src
    314     return render_template('admin_db_edit.html',db_edit_form=db_edit_form,db_table1=db_table1)
    315 
    316 #数据库管理/删
    317 @app.route('/admin_db/delete')
    318 @login_required
    319 @is_admin
    320 def admin_db_delete():
    321     delete_id = request.args.get('delete_id')
    322     db_table1 = DBTable.query.filter_by(id=delete_id).first()
    323     db.session.delete(db_table1)
    324     db.session.commit()
    325     return redirect(url_for('admin_db_query'))
    326 
    327 
    328 #用户管理/查
    329 @app.route('/admin_user/query',methods=['POST','GET'])
    330 @login_required
    331 @is_admin
    332 def admin_user_query():
    333     return render_template('admin_user_query.html',table1s=User.query.all())
    334 
    335 #用户管理/增
    336 @app.route('/admin_user/add',methods=['POST','GET'])
    337 @login_required
    338 @is_admin
    339 def admin_user_add():
    340     user_add_form = UserAddForm()
    341     if user_add_form.validate_on_submit():
    342         new_user = User(
    343             username=user_add_form.username.data,
    344             password=user_add_form.password.data
    345         )
    346         db.session.add(new_user)
    347         db.session.commit()
    348         return redirect(url_for('admin_user_query'))
    349     return render_template('admin_user_add.html',user_add_form=user_add_form)
    350 
    351 #用户管理/改
    352 @app.route('/admin_user/edit',methods=['POST','GET'])
    353 @login_required
    354 @is_admin
    355 def admin_user_edit():
    356     edit_id = request.args.get('edit_id')
    357     user1 = User.query.filter_by(id=edit_id).first()
    358     user_edit_form = UserEditForm()
    359     if user_edit_form.validate_on_submit():
    360         user1.username = user_edit_form.username.data
    361         user1.role_id = user_edit_form.role.data
    362         if user_edit_form.new_password.data:
    363             user1.password = user_edit_form.new_password.data
    364         db.session.add(user1)
    365         db.session.commit()
    366         return redirect(url_for('admin_user_query'))
    367     user_edit_form.username.data = user1.username
    368     user_edit_form.role.data = user1.role_id
    369     return render_template('admin_user_edit.html',user_edit_form=user_edit_form,user1=user1)
    370 
    371 #用户管理/删
    372 @app.route('/admin_user/delete',methods=['POST','GET'])
    373 @login_required
    374 @is_admin
    375 def admin_user_delete():
    376     delete_id = request.args.get('delete_id')
    377     user1 = User.query.filter_by(id=delete_id).first()
    378     db.session.delete(user1)
    379     db.session.commit()
    380     return redirect(url_for('admin_user_query'))
    381 
    382 
    383 if __name__ == '__main__':
    384     app.run(host="0.0.0.0", port=5000)
    app.py
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>首页</title>
     6         <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     7     <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     8     <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
     9 </head>
    10 <body>
    11 <div class="col-sm-6 col-sm-offset-3">
    12     <h2>登陆</h2><br>
    13     <form method="POST" action="{{ url_for('index') }}" >
    14         {{ login_form.hidden_tag() }}
    15         {{ login_form.username }}<br>
    16         {{ login_form.password }}<br>
    17         {{ login_form.submmit }}
    18     </form>
    19     <div>
    20     {% for msg in get_flashed_messages() %}
    21         {{ msg }}
    22     {% endfor %}
    23     </div>
    24 </div>
    25 
    26 </body>
    27 </html>
    index.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>搜索</title>
     6     <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     7     <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     8     <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
     9 </head>
    10 <body>
    11 <div class="col-sm-6 col-sm-offset-3">
    12 <h2>查询,查询,查询!</h2>
    13 <form method="POST" action="{{ url_for('search_db') }}" class="form-inline" >
    14     {{ search_form.hidden_tag() }}
    15     {{ search_form.search }}
    16     {{ search_form.kind }}
    17     {{ search_form.submmit }}
    18 </form>
    19 
    20 <br>
    21 {% for msg in get_flashed_messages() %}
    22     <strong style="color: red">{{ msg }}</strong>
    23 {% endfor %}
    24 <hr>
    25 <table border="1" class="table table-bordered">
    26     <thead>
    27         <tr class="info">
    28             <td><strong>来源</strong></td>
    29             <td><strong>用户</strong></td>
    30             <td><strong>密码</strong></td>
    31             <td><strong>邮箱</strong></td>
    32         </tr>
    33     </thead>
    34     {% for result_key,result_value in results.items() %}
    35         {% for result in result_value %}
    36         <tr>
    37             <td>{{ result_key }}</td>
    38             <td>{{ result.username }}</td>
    39             <td>{{ result.password }}</td>
    40             <td>{{ result.email }}</td>
    41         </tr>
    42         {% endfor %}
    43     {% endfor %}
    44 </table>
    45 </div>
    46 <div class="col-sm-2">
    47     <a href="{{ url_for('index') }}">logout</a>&nbsp;&nbsp;
    48     {% if current_user.username == 'admin' %}
    49     <a href="{{ url_for('admin_db_query') }}">后台</a>
    50     {% endif %}
    51     <br>欢迎{{ current_user.username }}<br>
    52     你的IP是:<{{ ip }}><br>
    53     不要乱搞呦!
    54 </div>
    55 </body>
    56 </html>
    search_db.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>后台管理</title>
     6     <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     7     <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     8     <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
     9 </head>
    10 <body>
    11 <div class="col-sm-6 col-sm-offset-3">
    12 <ul class="nav nav-tabs nav-justified">
    13  <li role="presentation" class="active"><a href="#">数据库管理</a></li>
    14   <li role="presentation"><a href="{{ url_for('admin_user_query') }}">用户管理</a></li>
    15   <li role="presentation"><a href="{{ url_for('search_db') }}">返回查询</a></li>
    16 </ul>
    17 <ul class="nav nav-pills nav-justified">
    18   <li role="presentation" ><a href="{{ url_for('admin_db_query') }}"></a></li>
    19   <li role="presentation" class="active"><a href="{{ url_for('admin_db_add') }}"></a></li>
    20   <li role="presentation"><a href="#"></a></li>
    21     <li role="presentation"><a href="#"></a></li>
    22 </ul>
    23 <hr>
    24     <div class="jumbotron">
    25             <h4>新增数据库说明</h4>
    26             <ul>
    27                 <li>本地数据库名必须为search_db</li>
    28                 <li>新增表名必须与数据库中表名完全一致</li>
    29                 <li>列名至少要包含username,password,email</li>
    30             </ul>
    31         </div>
    32     <div class="col-sm-10 col-sm-offset-1">
    33         <form method="POST" action="{{ url_for('admin_db_add') }}" >
    34         {{ db_add_form.hidden_tag() }}
    35         {{ db_add_form.table_name }}<br>
    36         {{ db_add_form.table_src }}<br>
    37         {{ db_add_form.submmit }}
    38     </form>
    39     </div>
    40 </div>
    41 </body>
    42 </html>
    admin_db_add.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>后台管理</title>
     6     <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     7     <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     8     <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
     9 </head>
    10 <body>
    11 <div class="col-sm-6 col-sm-offset-3">
    12 <ul class="nav nav-tabs nav-justified">
    13  <li role="presentation" class="active"><a href="#">数据库管理</a></li>
    14   <li role="presentation"><a href="#">用户管理</a></li>
    15   <li role="presentation"><a href="{{ url_for('search_db') }}">返回查询</a></li>
    16 </ul>
    17 <ul class="nav nav-pills nav-justified">
    18   <li role="presentation" ><a href="{{ url_for('admin_db_query') }}"></a></li>
    19   <li role="presentation" ><a href="{{ url_for('admin_db_add') }}"></a></li>
    20   <li role="presentation" class="active"><a href="#"></a></li>
    21     <li role="presentation"><a href="#"></a></li>
    22 </ul>
    23 <hr>
    24     <div class="jumbotron">
    25             <h4>修改数据库说明</h4>
    26             <ul>
    27                 <li>本地数据库名必须为search_db</li>
    28                 <li>新增表名必须与数据库中表名完全一致</li>
    29                 <li>列名至少要包含username,password,email</li>
    30             </ul>
    31         </div>
    32     <div class="col-sm-10 col-sm-offset-1">
    33         <form method="POST" action="{{ url_for('admin_db_edit',edit_id = db_table1.id) }}" >
    34         {{ db_edit_form.hidden_tag() }}
    35         {{ db_edit_form.table_name }}<br>
    36         {{ db_edit_form.table_src }}<br>
    37         {{ db_edit_form.submmit }}
    38     </form>
    39     </div>
    40 </div>
    41 </body>
    42 </html>
    admin_db_edit.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>后台管理</title>
     6     <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
     7     <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
     8     <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
     9 </head>
    10 <body>
    11 <div class="col-sm-6 col-sm-offset-3">
    12 <ul class="nav nav-tabs nav-justified">
    13  <li role="presentation" class="active"><a href="#">数据库管理</a></li>
    14   <li role="presentation"><a href="{{ url_for('admin_user_query') }}">用户管理</a></li>
    15   <li role="presentation"><a href="{{ url_for('search_db') }}">返回查询</a></li>
    16 </ul>
    17 <ul class="nav nav-pills nav-justified">
    18   <li role="presentation" class="active"><a href="{{ url_for('admin_db_query') }}"></a></li>
    19   <li role="presentation"><a href="{{ url_for('admin_db_add') }}"></a></li>
    20   <li role="presentation"><a href="#"></a></li>
    21     <li role="presentation"><a href="#"></a></li>
    22 </ul>
    23 <hr>
    24     <div class="col-sm-10 col-sm-offset-1">
    25         <table border="1" class="table table-bordered">
    26             <thead>
    27                 <tr class="info">
    28                     <td>id</td>
    29                     <td>表名</td>
    30                     <td>来源</td>
    31                     <td>操作</td>
    32                 </tr>
    33             </thead>
    34             {% for table in table1s %}
    35                 <tr>
    36                     <td>{{ table.id }}</td>
    37                     <td>{{ table.table_name }}</td>
    38                     <td>{{ table.table_src }}</td>
    39                     <td><a href="{{ url_for('admin_db_edit',edit_id = table.id) }}">修改</a>|<a href="{{ url_for('admin_db_delete',delete_id = table.id) }}">删除</a></td>
    40                 </tr>
    41             {% endfor %}
    42         </table>
    43     </div>
    44 </div>
    45 </body>
    46 </html>
    admin_db_query.html

    4.3 界面展示

    5、经验总结

    所有后端代码都写一个文件还是有点乱,下次还是分开

    用户登陆,权限控制应当制作成一个模块,以后每次复制粘贴就行了

  • 相关阅读:
    软件测试模型
    功能测试用例是怎么写
    Web测试需要注意的点
    WEB测试方法总结-笔记
    安全性测试的测试点
    删除功能测试的测试点
    压力测试的测试点
    异常测试的测试点
    解决Plugin org.apache.maven.plugins:maven-archetype-plugin:RELEASE or one of its dependencies...
    中国联通:本公司将继续在纽约证交所上市交易
  • 原文地址:https://www.cnblogs.com/cx59244405/p/10238303.html
Copyright © 2011-2022 走看看