zoukankan      html  css  js  c++  java
  • flask——简单博客示例教程(三)

    原文:https://blog.csdn.net/u014793102/article/category/9285123

    Flask从入门到做出一个博客的大型教程(三)

    在开始之前,先来看下项目的整体结构。

     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 数据库

    对于一个完整的网站数据库是很重要的,因为你的数据得有位置读取呀,网上很多数据库都用的sqlite,但是,我想使用mysql,所以接下来咱们就以mysql为数据库来讲解喽。

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

    这样就可以对数据库进行操作了,但是实际项目中会经常对数据库进行修改,但是一般不会手动的去数据库里进行改动,通常的做法是修改ORM对应的模型,然后再把模型映射到数据库中。在flask里有一个集成的工具是专门做这个事情的,安装它。

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

    因为我使用的是MySQL数据库,而在python3中不再支持mysqldb,因此我们还需要安装pymysql.

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

    需要的组件都安装好了,接下来在配置文件里配置数据库。

    app/config.py : 使用配置文件config.py中的内容

    1 import os
    2 BASE_DIR = os.path.abspath(os.path.dirname(__file__))
    3 class Config(object):
    4     #.......
    5     #格式为mysql+pymysql://数据库用户名:密码@数据库地址:端口号/数据库的名字?数据库格式
    6     SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@localhost:3306/flaskblog?charset=utf8'
    7     #如果你不打算使用mysql,使用这个连接sqlite也可以
    8     #SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR,'app.db')
    9     SQLALCHEMY_TRACK_MODIFICATIONS = False

    配置文件设置好了以后,就要对初始化文件进行修改。

    app/_ _ init_ _.py : 数据库的初始化设置

     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='duke@126.com')
    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='duke@126.com')
    3 #将实例添加
    4 >>> db.session.add(u)
    5 #提交
    6 >>> db.session.commit()

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

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

    1 >>> u = User(username='king',email='king@qq.com')
    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()
    本博客为记录本人遇到问题时所找到的解决方案,且均经过本人亲测可用,如有侵权请联系添加来源或删除文章,谢谢。
  • 相关阅读:
    django之验证码
    无法显示SQL Server Management Studio Express解决办法
    程序员常用不常见很难得的地址大全转
    调用ip138的页面获取IP地址
    VS 2010无法创建项目提示写入项目文件时出错 没有注册类别
    webapi token、参数签名是如何生成的(转载)
    尝试asp.net mvc 基于controller action 方式权限控制方案可行性(转载)
    委托学习
    Webapi上传数据(XML)敏感字符解决方案
    redis 学习
  • 原文地址:https://www.cnblogs.com/heymonkey/p/11721257.html
Copyright © 2011-2022 走看看