其实也就是三十几个人每个人可以报不同的物品,那么用FLASK写一个申报网站:
- 因为本次重点在多对多数据库方面,为了简化流程人员的注册和物品的注册都很简单
首先是根目录下的setting 配置文件,
class Config(object):
DEBUG=1
SQLALCHEMY_DATAbase_URI="mysql+pymysql://root:gxxxe@47.xxx.xx.xxx:3306/mysqllaobao"
SQLALCHEMY_TRACK_MODIFICATIONS=False
EVN='development'
SECRET_KEY = 'ASDFJASKDaskdlfjla123'
- 然后是,入口app.py,因为做了分离,所以这个入口几乎也是万能的,新项目直接配套沾走环境一致也能用
from flask import Flask
from apps import creat_app
from exts import db
from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand
from apps.modles import *
app = Flask(__name__)
app=creat_app(app)
manage = Manager(app=app)
migrate = Migrate(app=app,db=db)
manage.add_command('db',MigrateCommand)
if __name__ == '__main__':
manage.run()
- 根目录下laobao.txt 这个是环境配置文件,用下面这个命令可以安装对应环境
pip instal -r laobao.txt
文件内容如下:
alembic==1.7.1 backcall==0.2.0 Bootstrap-Flask==1.8.0 click==8.0.1 colorama==0.4.4 decorator==5.1.0 dominate==2.6.0 easygui==0.98.2 Flask==1.1.2 Flask-Admin==1.5.8 Flask-Bootstrap==3.3.7.1 Flask-Migrate==2.5.3 Flask-script==2.0.6 Flask-SQLAlchemy==2.5.1 greenlet==1.1.1 importlib-metadata==4.8.1 importlib-resources==5.2.2 ipython==7.27.0 itsdangerous==2.0.1 jedi==0.18.0 Jinja2==3.0.1 Mako==1.1.5 MarkupSafe==2.0.1 matplotlib-inline==0.1.3 paho-mqtt==1.5.1 parso==0.8.2 pickleshare==0.7.5 prompt-toolkit==3.0.20 Pygments==2.10.0 PyMySQL==1.0.2 SQLAlchemy==1.4.23 traitlets==5.1.0 typing-extensions==3.10.0.2 visitor==0.1.3 wcwidth==0.2.5 Werkzeug==2.0.1 WTForms==2.3.3 zipp==3.5.0
4./apps/init 里边是工厂函数,也是不用太管的玩意,
from setting import Config
from exts import db
from apps.views import user_bp
def creat_app(app):
app.config.from_object(Config)
app.register_blueprint(user_bp)
db.init_app(app)
return app
- /exts/init 数据库映射扩展
from flask_sqlalchemy import SQLAlchemy db=SQLAlchemy()
- /apps/modles.py 模型位置 ,三个模型 一个人的就一个名字
一个东西的也一个名字,一个关系模型
from exts import db
from datetime import datetime
class Person(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(20),nullable=False)
thing=db.relationship('Thing',backref='person',secondary='guan_xi')#这里第一个是类名字所以是大写头字母的Thing,后面都是数据库中的表名所以都小写。
def __str__(self):
return self.u_id
class Thing(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(20),nullable=False)
def __str__(self):
return self.t_id
class GuanXi(db.Model):#这里好坑
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
u_id = db.Column(db.Integer,db.ForeignKey('person.id'))
t_id = db.Column(db.Integer,db.ForeignKey('thing.id'))
numbers= db.Column(db.String(20),nullable=False)
def __str__(self):
return self.g_id
- 构建逻辑把。。首先视图函数首页,
from flask import render_template ,request,session,redirect,g
from flask import Blueprint
from exts import db
from apps.modles import *
user_bp = Blueprint('user',__name__)
@user_bp.route('/')
def start():
return render_template('index.html')
index.html为:
Title
查询页面
页面效果这样,灰常简单
8. 第三个页面应该是购买记录,忘记改了,算了就这么地吧。配套三个路由如下,虽然很长,但基本一个逻辑。
@user_bp.route('/login',methods=['GET','POST'])
def login():
if request.method == 'POST':
name = request.form.get('name')
print(name)
person=Person()
person.name=name
db.session.add(person)
db.session.commit()
return 'nihao'#页面不写了,进去就行
return render_template('index.html')
@user_bp.route('/wupinlogin',methods=['GET','POST'])
def wupinlogin():
if request.method == 'POST':
name = request.form.get('name')
print(name)
thing=Thing()
thing.name=name
db.session.add(thing)
db.session.commit()
return '东西'
return render_template('index.html')
@user_bp.route('/goumai',methods=['GET','POST'])
def goumai():
if request.method == 'POST':
name = request.form.get('name')
thing = request.form.get('thing')
numbers = request.form.get('numbers')
guanxi=GuanXi()
guanxi.u_id=Person.query.filter(Person.name==name).first().id #根据名字找编号然后存
guanxi.t_id = Thing.query.filter(Thing.name == thing).first().id
guanxi.numbers = numbers
db.session.add(guanxi)
db.session.commit()
return '东西'
return render_template('index.html')
- 查询路由,这个路由相对要复杂一些,HTML那里采用GET方式传参数,这边路由接收。
@user_bp.route('/chaxun',methods=['GET','POST'])
def chaxun():
person=Person.query.all()#查询全体,这里主要是给最底下那个页面服务的,跟中间逻辑没啥关系
thing = Thing.query.all()#查询全体,这里主要是给最底下那个页面服务的,跟中间逻辑没啥关系
name = request.args.get('name')#拿参数
wupin = request.args.get('wupin')
if name :
person=Person.query.filter(Person.name==name).first()#查询到具体人的一行
for i in person.thing :#用这个人行的点东西,可以弄出东西表的对应的多个行内容,用FOR展开
print(i.name)#遍历拿多个物品名字
print(GuanXi.query.filter(GuanXi.t_id==i.id).first().numbers)#这一行是去关系行找对应数量
return '啊不写页面了,打印能看见就得了'
else :
print('没有查询用户')
if wupin :
things = Thing.query.filter(Thing.name == wupin).first()
print('本次查询的是:')
for i in things.person:
print(i.name)
print(GuanXi.query.filter(GuanXi.t_id == i.id).first().numbers)
print('查询完毕')
return '唔,不写不写'
else:
print('没有查询物品')
return render_template('chaxun.html',person=person,thing=thing)
配套chaxun.html页面
Title
{% for i in person %}
{{ i.name }}
{% endfor %}
{% for i in thing %}
{{ i.name }}
{% endfor %}
很多内容写在注释里了,注意看下。
避坑指南:在网页提交内容的时候尽量避免中文名的出现,毕竟有的时候中文会有乱码坑,所以变通的做法是HTML页面显示的用户以及物品的名字,传送的是对应的ID号,这样比较稳妥,反正查询的时候对应着id更方便些


