【100Days of 100 line Code】9 day and 10 day

前两天在帮一哥们做一个往数据库加数据的页面,基于python Flask框架。

赶鸭子上架简直,之前加入的时候大言不惭的告诉那哥们会Django和Flask。

说实话,Django也就看了个基础。Flask也就这是知道一个名字。数据库也没有用过,花了一天时间到晚上一点,数据库才弄好。

又是整整一天研究了pymysql和SQLAlchemy才把python和数据库连上。

周六周日都没怎么有空,今天把代码回顾一下。

割一下--------------

需求:

必要参数(在数据库中保存的就是这样的):
commodityName    商品名称

commodityPic         商品图片
考虑到一种商品会有多张图片的情况,在数据库以图片路径的形式保存,
路径格式为:/image/commodityImg/商品编号/img_图片I.jpg   多张图片路径中间以英文逗号隔开 
例如/image/commodityImg/1/img_1.jpg,/image/commodityImg/1/img_2.jpg   即为第一件商品的第一张和第二张图片

briefInfo                  简要信息
商品的简要信息


detailedInfo            详细信息
详细信息目前暂定也是用图片的形式来展现,所以详细信息这里也是存放图片路径的,
格式只有在图片命名上略有不同:/image/commodityImg/1/detail_1.jpg  多张图片路径中间以英文逗号隔开 
例如/image/commodityImg/1/detail_1.jpg,/image/commodityImg/1/detail_2.jpg   即为第一件商品的第一张和第二张详情


price                        价格

like                          点赞数量(暂定) 
每次填300就行了 暂定功能,以后可能会改
sex                           面向人群性别
1代表男性 0代表女性 填1或0就完事了


有个地方要说一下,后台更新商品是肯定要上传图片的,
商品图片上传路径是/home/static/commodityImg/商品编号/img_商品编号.jpg
详情图片上传路径是/home/static/commodityImg/商品编号/detail_商品编号.jpg

一,数据库的安装

工具:

MySql-8.0.11,Navicat 12 for MySQL

MySQL下载地址:https://dev.mysql.com/downloads/mysql/

Navicat 12 for MySQL下载地址:https://www.navicat.com/en/download/navicat-for-mysql

MySQL的安装真是要了老命,花了N种方法N个小时。

1.下载,解压到路径

2.配置环境变量

我的电脑>>属性>>环境变量>>系统环境变量>>path,将mysql的解压路径/bin复制到变量内

3.配置文件

我下载下来的时候 是没有配置文件的,听说大部分人都没有。。

配置文件命名:my.ini

代码:

[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=G:mysql   
# 设置mysql数据库的数据的存放目录
datadir=G:mysqlin 
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
# 服务端使用的字符集默认为UTF8
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8

4.安装MySQL

务必使用管理员权限进入命令行

cd到安装目录的/bin

输入命令对mysql进行初始化

mysqld --initialize --console

执行结果会有一段: [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: rI5rvf5x5G,E 其中root@localhost:后面的“rI5rvf5x5G,E”就是初始密码(不含首位空格)。在没有更改密码前,需要记住这个密码,后续登录需要用到。

输入命令安装MySQL

mysqld --install [服务名]

有多个MySQL服务的话,服务名要对应相应的MySQL服务

输入命令开启MySQL服务

net start mysql

开启之后,就可以登陆数据库了

登陆数据库命令

mysql -u root -p

后面会叫你输入密码,这个时候输入刚刚的密码

更改数据库登陆密码

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';  

(ps:分号一定要有,python写多了习惯了不写分号,但是数据库是不会执行命令的)

后连接Navicat 12 for MySQL,创建表即可。

二,Flask虚拟环境

我直接用的是PyCharm,可以生成Flask所需的虚拟环境。

注意一下,Flask所需要的模块,需要下载到虚拟环境的编译器文件夹内,否则会无法运行

下载方式和正常的下载模块方式一致,有路径的区别

三.Flask连接数据库

我用的是flask_sqlalchemy这个模块连接的数据库。

引入的库:

from flask_sqlalchemy import SQLAlchemy

安装方法:

虚拟环境下安装flask_sqlalchemy模块

(venv) G:commodity>pip install flask_sqlalchemy

数据库配置:

配置代码我直接写在app.py里面了,这样是不好的听说,要专门新建一个confit.py保存配置是最好的

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:111111@127.0.0.1:3306/commodity?charset=utf8'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SECRET_KEY'] = 'xcax0cx86x04x98@x02bx1b7x8cx88]x1bxd7"+xe6px@xc3#\'

第一行是数据库的配置文件:规范是mysql+pymysql://用户名:密码@地址:端口/数据库名?编码

第二行该配置为True,则每次请求结束都会自动commit数据库的变动

第三行是生成一个密匙,CSRF需要用到

定义模型

定义模型主要是关联数据库的表,

class Commpdity(db.Model):
    __tablename__ = 'commodity'
    commodityID = db.Column(db.Integer, primary_key=True)
    commodityName = db.Column(db.Text)
    briefInfo = db.Column(db.Text)
    price = db.Column(db.Float)
    like = db.Column(db.Integer)
    sex = db.Column(db.Text)

一定要有一个primary_key 的值为true,否则会报错

四.表单

引入的库

from wtforms import StringField, IntegerField, SubmitField, FloatField
from wtforms.validators import DataRequired, Length, Regexp
from flask_wtf import FlaskForm
from flask_wtf.file import FileField

第一行是表单所引用的字段类型

第二行是表单验证所引用的验证函数。空值验证,长度验证,正则表达式验证

第三行是引入表单

第四行是文件处理所使用的模型

下面是具体的表单代码

class AddCommodity(FlaskForm):
    commodityName = StringField('商品名称', validators=[DataRequired(message=u'商品名不能为空'), Length(1, 60),
            Regexp('^[A-Za-z][A-Za-z0-9/ ]*$', 0, '商品名称只允许使用汉字,英文,数字,空格和右斜杠')])  # 商品名称 文字
    briefInfo = StringField(u'商品卖点', validators=[DataRequired(message=u'商品卖点不能为空'), Length(1, 60),
            Regexp('^[A-Za-z][A-Za-z0-9/ ]*$', 0, '商品卖点只允许使用汉字,英文,数字,空格和右斜杠')])   # 商品卖点 文字
    price = FloatField(u'商品价格', validators=[DataRequired(message=u'商品价格不能为空')])  # 价格 浮点类型
    like = IntegerField(u'点赞次数', validators=[DataRequired(message=u'点赞次数不能为空')])  # 点赞
    sex = IntegerField(u'面向人群', validators=[DataRequired(message=u'面向人群不能为空')])  # 选择 男或女
    submit = SubmitField(u'发布商品')

五.对数据库的操作

@app.route('/', methods=['GET', 'POST'])  # 路由设置
def hello_world():
    form = AddCommodity() 
    if form.validate_on_submit():  # 当表单内容提交
        new_id = db.session.query(func.count(Commpdity.commodityID)).scalar() + 1
        path = '/home/static/commodityImg/' + str(new_id)
        os.makedirs(path)
        filename = form.commodityPic.data.filename
        form.commodityPic.data.save(path + filename)
        commodity = Commpdity(                     # 数据库内容提交
            commodityID=new_id,
            commodityName=form.commodityName.data,
            commodityPic=form.commodityPic.data,
            briefInfo=form.briefInfo.data,
            detailedInfo=form.detailedInfo.data,
            price=form.price.data,
            like=form.like.data,
            sex=form.sex.data
        )
        db.session.add(commodity)  # 保存表格数据到数据库
        db.session.commit()  # commit数据库
        flash('商品已经成功发布')
    return render_template('/addcommodity.html',form=form)

六.页面

{% import "bootstrap/wtf.html" as wtf %}
{% block page_content %}
<div class="page-header">
    <h1>发布商品</h1>
</div>
<div class="col-md-4">
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}

目前还没有实现的功能:

一. 上传图片功能,

虽然有办法实现,但是不知道页面和流程怎么设计

二.  图片更名

有方法实现,问题同上

具体的代码:

app.py
from flask import Flask
from flask import flash, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from forms import AddCommodity
from sqlalchemy import func
import os
from werkzeug import secure_filename
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:111111@127.0.0.1:3306/commodity?charset=utf8'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SECRET_KEY'] = 'xcax0cx86x04x98@x02bx1b7x8cx88]x1bxd7"+xe6px@xc3#\'
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)


@app.route('/', methods=['GET', 'POST'])  # 路由设置
def hello_world():
    form = AddCommodity()
    if form.validate_on_submit():  # 当表单内容提交
        new_id = db.session.query(func.count(Commpdity.commodityID)).scalar() + 1
        path = '/home/static/commodityImg/' + str(new_id)
        os.makedirs(path)
        filename = form.commodityPic.data.filename
        form.commodityPic.data.save(path + filename)
        commodity = Commpdity(                     # 数据库内容提交
            commodityID=new_id,
            commodityName=form.commodityName.data,
            commodityPic=form.commodityPic.data,
            briefInfo=form.briefInfo.data,
            detailedInfo=form.detailedInfo.data,
            price=form.price.data,
            like=form.like.data,
            sex=form.sex.data
        )
        db.session.add(commodity)  # 保存表格数据到数据库
        db.session.commit()  # commit数据库
        flash('商品已经成功发布')
    return render_template('/addcommodity.html',form=form)


if __name__ == '__main__':
    app.run(debug=True)


class Commpdity(db.Model):
    __tablename__ = 'commodity'
    commodityID = db.Column(db.Integer, primary_key=True)
    commodityName = db.Column(db.Text)
    commodityPic = db.Column(db.Text)
    briefInfo = db.Column(db.Text)
    detailedInfo = db.Column(db.Integer)
    price = db.Column(db.Float)
    like = db.Column(db.Integer)
    sex = db.Column(db.Text)

forms.py
from wtforms import StringField, IntegerField, SubmitField, FloatField
from wtforms.validators import DataRequired, Length, Regexp
from flask_wtf import FlaskForm
from flask_wtf.file import FileField


class AddCommodity(FlaskForm):
    commodityName = StringField('商品名称', validators=[DataRequired(message=u'商品名不能为空'), Length(1, 60),
            Regexp('^[A-Za-z][A-Za-z0-9/ ]*$', 0, '商品名称只允许使用汉字,英文,数字,空格和右斜杠')])  # 商品名称 文字
    commodityPic = FileField(u'商品主图')  # 商品主图 图片文件
    briefInfo = StringField(u'商品卖点', validators=[DataRequired(message=u'商品卖点不能为空'), Length(1, 60),
            Regexp('^[A-Za-z][A-Za-z0-9/ ]*$', 0, '商品卖点只允许使用汉字,英文,数字,空格和右斜杠')])   # 商品卖点 文字
    detailedInfo = FileField(u'上传商品详情',)  # 详细介绍 图片文件
    price = FloatField(u'商品价格', validators=[DataRequired(message=u'商品价格不能为空')])  # 价格 浮点类型
    like = IntegerField(u'点赞次数', validators=[DataRequired(message=u'点赞次数不能为空')])  # 点赞
    sex = IntegerField(u'面向人群', validators=[DataRequired(message=u'面向人群不能为空')])  # 选择框 男或女
    submit = SubmitField(u'发布商品')
addcommodity.html
{% import "bootstrap/wtf.html" as wtf %}
{% block page_content %}
<div class="page-header">
    <h1>发布商品</h1>
</div>
<div class="col-md-4">
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}
原文地址:https://www.cnblogs.com/mygzhh/p/9354272.html