flask-- simple blog example tutorial (Three)

Original: https://blog.csdn.net/u014793102/article/category/9285123

Flask from a blog entry to make large tutorial (Three)

Before you begin, first look at the overall structure of the project.

 1 flask
 2 ├── app
 3 │   ├── forms.py
 4 │   ├── __init__.py
 5 │   ├── routes.py
 6 │   └── templates
 7 │       ├── base.html
 8 │       ├── index.html
 9 │       └── login.html
10 ├── config.py
11 ├── myblog.py

4 database

For a complete site database is very important because you have to have location data to read it, many online databases are used sqlite, but I want to use mysql, so then we will go to the mysql database to explain myself.

1 (venv) duke@coding:~/flask_tutorial/flask$ pip install flask-sqlalchemy

So that you can operate the database, but the actual projects often changes to the database, but generally do not manually make changes to the database, the usual practice is to modify the corresponding ORM model, then put into a database mapping model . There is an integrated tool is designed to do this thing in the flask where to install it.

1 (venv) duke@coding:~/flask_tutorial/flask$ pip install flask-migrate

Because I'm using a MySQL database, but in python3 no longer supported mysqldb, so we also need to install pymysql.

1 (venv) duke@coding:~/flask_tutorial/flask$ pip install pymysql

Required components are installed, the next configuration database in the configuration file.

app / config.py: Use content profiles in config.py

. 1  Import OS
 2 base_dir = os.path.abspath with (os.path.dirname ( __FILE__ ))
 . 3  class Config (Object):
 . 4      # ....... 
. 5      # format mysql + pymysql: // database username : password @ database address: port number / name of the database database format? 
6      SQLALCHEMY_DATABASE_URI = ' MySQL + pymysql: // root: 123456 @ localhost:? 3306 / flaskblog charset = utf8 ' 
7      # If you do not plan to use mysql, use this sqlite may be connected 
. 8      # SQLALCHEMY_DATABASE_URI = 'sqlite: ///' + the os.path.join (base_dir, 'app.db') 
. 9      SQLALCHEMY_TRACK_MODIFICATIONS = False

After the profile set up, it is necessary to modify the initialization file.

app / _ _ init_ _.py: initial setup of the database

 1 from flask import Flask
 2 from config import Config
 3 from flask_sqlalchemy import SQLAlchemy
 4 from flask_migrate import Migrate
 5 app = Flask(__name__)
 6 app.config.from_object(Config)
 7 #建立数据库关系
 8 db = SQLAlchemy(app)
 9 #绑定app和数据库,以便进行操作
10 migrate = Migrate(app,db)
11 
12 from app import routes,models

接下来比较重要的就是设计模型了,model是模型的映射,只有设计好model才能进行一系列的操作。新建一个models.py文件。

1 (venv) duke@coding:~/flask_tutorial/flask$ touch app/models.py

app/models.py : 用户数据库模型

 1 from app import db
 2 
 3 class User(db.Model):
 4     __tablename__ = 'user'
 5     id = db.Column(db.Integer,primary_key=True)
 6     username = db.Column(db.String(64),index=True,unique=True)
 7     email = db.Column(db.String(120),index=True,unique=True)
 8     password_hash = db.Column(db.String(128))
 9 
10     def __repr__(self):
11         return '<用户名:{}>'.format(self.username)

对模型进行验证:

1 (venv) duke@coding:~/flask_tutorial/flask$ python
2 Python 3.6.4 (default, May  3 2018, 19:35:55) 
3 [GCC 5.4.0 20160609] on linux
4 Type "help", "copyright", "credits" or "license" for more information.
5 >>> from app.models import User
6 >>> u = User(username='duke',email='[email protected]')
7 >>> u
8 <用户名:duke>

对模型验证后,发现是正确的,进行数据库初始化。

1 (venv) duke@coding:~/flask_tutorial/flask$ flask db init
2   Creating directory /home/duke/flask_tutorial/flask/migrations ... done
3   Creating directory /home/duke/flask_tutorial/flask/migrations/versions ... done
4   Generating /home/duke/flask_tutorial/flask/migrations/script.py.mako ... done
5   Generating /home/duke/flask_tutorial/flask/migrations/alembic.ini ... done
6   Generating /home/duke/flask_tutorial/flask/migrations/README ... done
7   Generating /home/duke/flask_tutorial/flask/migrations/env.py ... done
8   Please edit configuration/connection/logging settings in
9   '/home/duke/flask_tutorial/flask/migrations/alembic.ini' before proceeding.

现在看一看项目结构

 1 flask
 2 ├── app
 3 │   ├── forms.py
 4 │   ├── __init__.py
 5 │   ├── models.py
 6 │   ├── routes.py
 7 │   └── templates
 8 │       ├── base.html
 9 │       ├── index.html
10 │       └── login.html
11 ├── config.py
12 ├── migrations
13 │   ├── alembic.ini
14 │   ├── env.py
15 │   ├── README
16 │   ├── script.py.mako
17 │   └── versions
18 ├── myblog.py

接下来创建数据库的管理工具。

1 (venv) duke@coding:~/flask_tutorial/flask$ flask db migrate -m 'users_table'
2 INFO  [alembic.runtime.migration] Context impl MySQLImpl.
3 INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
4 INFO  [alembic.autogenerate.compare] Detected added table 'user'
5 INFO  [alembic.autogenerate.compare] Detected added index 'ix_user_email' on '['email']'
6 INFO  [alembic.autogenerate.compare] Detected added index 'ix_user_username' on '['username']'
7   Generating
8   /home/duke/flask_tutorial/flask/migrations/versions/06ea43ff4439_users_table.py
9   ... done

创建数据库的中的表。

1 (venv) duke@coding:~/flask_tutorial/flask$ flask db upgrade
2 INFO  [alembic.runtime.migration] Context impl MySQLImpl.
3 INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
4 INFO  [alembic.runtime.migration] Running upgrade  -> 06ea43ff4439, users_table

执行到这里,表已经在数据库中建立完成。或许你会问,这和我以前的接触过的不一样啊,这么会麻烦这么多,因为你对数据库模型修改后,可以很方便的进行数据库表的迁移,这会大大的减少以后可能会发生的大量的工作量。

网站里不可能只有一张表的,多张表之间肯定会有联系,接下来对表之间的关系进行一个详细介绍。

app/models.py : 添加一张新表,并建立关系

 1 from datetime import datetime
 2 from app import db
 3 
 4 class User(db.Model):
 5     __tablename__ = 'user'
 6     id = db.Column(db.Integer,primary_key=True)
 7     username = db.Column(db.String(64),index=True,unique=True)
 8     email = db.Column(db.String(120),index=True,unique=True)
 9     password_hash = db.Column(db.String(128))
10     # back是反向引用,User和Post是一对多的关系,backref是表示在Post中新建一个属性author,关联的是Post中的user_id外键关联的User对象。
11     #lazy属性常用的值的含义,select就是访问到属性的时候,就会全部加载该属性的数据;joined则是在对关联的两个表进行join操作,从而获取到所有相关的对象;dynamic则不一样,在访问属性的时候,并没有在内存中加载数据,而是返回一个query对象, 需要执行相应方法才可以获取对象,比如.all()
12     posts = db.relationship('Post',backref='author',lazy='dynamic')
13 
14     def __repr__(self):
15         return '<用户名:{}>'.format(self.username)
16 
17 class Post(db.Model):
18     __tablename__ = 'post'
19     id = db.Column(db.Integer,primary_key=True)
20     body = db.Column(db.String(140))
21     timestamp = db.Column(db.DateTime,index=True,default=datetime.utcnow)
22     user_id = db .Column(db.Integer,db.ForeignKey('user.id'))
23 
24     def __repr__(self):
25         return '<Post {}>'.format(self.body)

生成新的数据库关系:

1 (venv) duke@coding:~/flask_tutorial/flask$ flask db migrate -m 'posts_table'
2 INFO  [alembic.runtime.migration] Context impl MySQLImpl.
3 INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
4 INFO  [alembic.autogenerate.compare] Detected added table 'post'
5 INFO  [alembic.autogenerate.compare] Detected added index 'ix_post_timestamp' on '['timestamp']'
6   Generating /home/miguel/microblog/migrations/versions/780739b227a7_posts_table.py ... done

提交到数据库中:

1 (venv) duke@coding:~/flask_tutorial/flask$ flask db upgrade
2 INFO  [alembic.runtime.migration] Context impl MySQLImpl.
3 INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
4 INFO  [alembic.runtime.migration] Running upgrade  -> 780739b227a7, posts_table

接下来使用shell对进行操作:

1 (venv) duke@coding:~/flask_tutorial/flask$ python
2 Python 3.6.4 (default, May  3 2018, 19:35:55) 
3 [GCC 5.4.0 20160609] on linux
4 Type "help", "copyright", "credits" or "license" for more information.
5 >>> from app import db
6 >>> from app.models import User,Post

在用户表中添加一条用户信息:

1 #创建一个User对象实例
2 >>> u = User(username='duke',email='[email protected]')
3 #将实例添加
4 >>> db.session.add(u)
5 #提交
6 >>> db.session.commit()

查看数据库后发现,插进一条数据。

在用户表中添加另外一条用户信息:

1 >>> u = User(username='king',email='[email protected]')
2 >>> db.session.add(u)
3 >>> db.session.commit()

通过查询数据库发现也插进了一条数据,但是怎么查询的呢?

查询数据库中信息:

1 >>> users = User.query.all()
2 >>> users
3 [<用户名:duke>, <用户名:king>]
4 >>> for u in users:
5 ...     print(u.id,u.username)
6 ... 
7 1 duke
8 2 king

这是一次性全部查询,那能不能查单条数据呢?答案是肯定的喽。

1 #根据id可以查询到数据
2 >>> u = User.query.get(2)
3 >>> u
4 <用户名:king>

普通的数据库表咱们会了,那么有外键关联的一对多中数据库表怎么插入数据呢?

 1 #查找到一个User对象
 2 >>> u = User.query.get(1)
 3 #将该User对象与Post建立关系
 4 >>> p = Post(body='我第一次提交数据!',author=u)
 5 >>> db.session.add(p)
 6 >>> db.session.commit()
 7 #插入第二条数据,但是拥有者都是同一个人
 8 >>> p = Post(body='我第二次提交数据了!',author=u)
 9 >>> db.session.add(p)
10 >>> db.session.commit()

现在通过查询来让你更加的熟悉一对多的关系。

 1 # 获得一个用户的所有提交
 2 >>> u = User.query.get(1)
 3 >>> u
 4 <用户名:duke>
 5 #u.posts.all()中的posts是model中的,User和Post关联的作用。
 6 >>> posts = u.posts.all()
 7 >>> posts
 8 [<Post 我第一次提交数据!>, <Post 我第二次提交数据了!>]
 9 
10 #进行相同的操作,但是换成另外一名用户
11 >>> u = User.query.get(2)
12 >>> u
13 <用户名:king>
14 >>> u.posts.all()
15 []
16 
17 #对所有的posts进行查询
18 >>> posts = Post.query.all()
19 >>> for p in posts:
20 ...     print(p.id,p.author.username,p.body)
21 ... 
22 1 duke 我第一次提交数据!
23 2 duke 我第二次提交数据了!
24 
25 #还可以按照一定的规则进行查询
26 >>> User.query.order_by(User.username.desc()).all()
27 [<用户名:king>, <用户名:duke>]

熟悉了查询,接下来就把刚才的测试数据都删除吧!

1 >>> users = User.query.all()
2 >>> for u in users:
3 ...     db.session.delete(u)
4 ... 
5 >>> posts = Post.query.all()
6 >>> for p in posts:
7 ...     db.session.delete(p)
8 ... 
9 >>> db.session.commit()

Guess you like

Origin www.cnblogs.com/heymonkey/p/11721257.html