Python-Flask框架
2018-10-16 本文已影响0人
云中的Jason
(本文后期会重新整理,敬请期待)
URL和视图
安装Homebrew
在终端输入以下代码,安装Homebrew:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Python安装
mac环境下默认安装了python 2.7,安装3.6需要用以下代码:
brew install python3
Python虚拟环境安装
- 因为python的框架版本更新迭代速度太快,有时需要在一台电脑上存在一个框架的多个版本,这时就需要虚拟环境。通过以下代码安装:
pip3 install virtualenv
- 虚拟环境管理工具virtualenvwrapper可以很便捷的新建、删除、切换虚拟环境。virturalenvwrapper可以通过一下代码安装:
pip3 install virtualenvwrapper
- 在使用virturalenvwrapper之前,需要对 virtualenvwrapper 进行配置。它需要指定一个环境变量,叫做 WORKON_HOME,并且需要运行一下它的初始化工具 virtualenvwrapper.sh,这个脚本默认安装在 /usr/local/bin/ 目录下。WORKON_HOME 就是它将要用来存放各种虚拟环境目录的目录,这里我们可以设置为 ~/.Python/Envs。通过以下方式将配置代码加入.bash_profile中
修改方式
vim .bash_profile
open -e .bash_profile
配置代码
export WORKON_HOME=$HOME/.Python/Envs
export VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3
source /usr/local/bin/virtualenvwrapper.sh
- virtualenvwrapper常用指令:
mkvirtualenv env1 //创建虚拟环境
workon //列出虚拟环境
workon Flask_env //使用虚拟环境env1
deactivate //退出虚拟环境
rmvirtualenv env1 //删除虚拟环境env1
flask 安装
进入创建的虚拟环境,在虚拟环境下安装flask,安装指令如下:
pip3 install flask
第一个flask程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello world!'
if __name__ == '__main__'
app.run()
debug 模式
- 在app.run()中传入一个关键字参数debug,app.run(debug=Ture),就设置当前项目为debug模式。
- debug模式的两大功能:
- 当程序出现问题时,可以在页面中看到错误信息和出错的位置。
- 只要修改了项目中的Python文件,程序会自动加载,不需要手动重启服务器。
使用配置文件
- 新建一个'config.py'文件
- 在主app文件中导入这个文件,并且配置到app中,示例代码如下
import config
app.config.from_object(config)
- 还有许多的其他参数,都是放在这个配置文件中,比如‘SECRET_KEY‘和’SQLALCHEMY‘。
URL 传参
- 参数的作用:可以在相同的URL中指定不同的参数,来加载不同的数据。
- 在flask中使用参数:
@app.route('/article/<id>')
def article(id):
return u'你请求的参数是:%s' % id
* 参数需要放在两个尖括号中
* 视图函数中需要放和url中的参数同名的参数
URL 反转
- 什么叫反转URL:从视图函数到URL的转换叫做反转URL
href="{{ url_for('index') }}"
- 反转URL的用处
- 在页面重定向的时候,会使用URL反转
- 在模版中,也会使用URL反转
页面跳转和重定向
- 用处:在用户访问一些需要登录的界面时,如果用户没有登录,那么可以让它重定向到登录页面
- 代码实现:
from flask import Flask,redirect,url_for
redirect(url_for('login'))
Jinjia2模版
Flask渲染Jinjia2模版和传参
- 如何渲染模版
- 模版放在‘templates’文件夹下
- 从‘flask’中导入‘render_template’函数
- 从视图函数中,使用‘render_template’函数,渲染模版。注意,只需要填写模版的名字,不需要填写‘templates’这个文件路径
- 模版传参:
- 如果只有一个或少量参数,直接在‘render_template’函数中添加关键字参数就可以了。
- 如果有多个参数,那么可以先把所有的参数放到字典中,然后在‘render_template’中,使用**将字典转换成关键参数传递进去,这样的代码更方便管理和使用。
- 在模版中,使用一个变量的语法是
{{ params }}
- 访问模版中的属性或是字典,可以通过
{{ params.property }}
的形式,或者使用{{ params['property'] }}
。
if判断语句
- 语法
{% if xxx %}
{% eles %}
{% endif %}
- if的使用和python相差无几
for循环遍历
- 字典的遍历语法和python一样,可以使用‘items()’、‘keys()’、‘values()’、‘iteritems()’、‘iterkeys()’、‘itervalues()’
{% for k,v in user.items() %}
<p>{{ k }}:{{ v }}</p>
{% endfor %}
- 列表的遍历与python一样
{% for website in websites %}
<p>{{ website }}</p>
{% endfor %}
过滤器
- 介绍和语法
- 介绍:过滤器可以处理变量,把原始的变量经过处理后再展示出来,作用的对象是变量
- 语法:
{{ params|default('xxx') }}
- default过滤器:如果当前变量不存在,这时候可以指定默认值
- length过滤器:求列表、字符串、字典和元祖的长度
{{ params|length }}
继承和block
- 继承的作用和语法
- 作用:可以把公共的代码放在父模版中,避免每一个模版写同样的代码
- 语法:
{% extends 'base.html' %}
- block实现:
- 作用:可以让子模版实现自己的需求,父模版需要提前定义
<!--接口-->
{% block main %}{% endblock%}
- 注意点:子模版中的代码必须放在block块中
{% block main %}
<h1>这是登录页面</h1>
{% endblock %}
URL链接和加载静态文件
- 使用‘url_for(视图函数名称)’可以反转成url
- 加载静态文件:
- 语法:‘url_for('static',filename='路径')’
- flask会从‘static’文件夹中开始寻找,不需要写‘static’这个路径
- 可以加载css、js、image文件
<link href="{{ url_for('static',filename='css/static.css') }}" rel="stylesheet" type="text/css" />
<script src="{{ url_for('static',filename='js/static.js') }}"></script>
SQLAlchemy数据库
Mac下数据库的安装
- MySql下载链接
- Mac上安装Mysql后,在系统偏好设置里启动MySql服务
- 配置环境变量:
- 进入/usr/local/mysql/bin,查看此目录下是否有mysql
- 执行以下指令:
进入vim
vim ~/.bash_profile
添加mysql路径
PATH=$PATH:/usr/local/mysql/bin
按esc,输入‘:wq’保存退出
激活配置文件
source ~/.bash_profile
- 数据库相关指令:
mysql -u username -p
show databases
mysqlclient安装
- 进入虚拟环境,安装mysql-connector-c
brew install mysql-connector-c
- 修改mysql_config文件的配置,位于/usr/local/bin/mysql_config
原代码:
libs="-L$pkglibdir"
libs="$libs -l "
更改后代码:
libs="-L$pkglibdir"
libs="$libs -lmysqlclient -lssl -lcrypto"
- 安装mysqlclient:
pip3 install mysqlclient
Flask-SQLAlchemy的介绍与安装
- ORM:Object Relationship Mapping(模型关系映射)
- flask-sqlalchemy是一套ORM框架
- ORM的好处:可以让我们操作数据库和操作对象一样,非常方便。因为一个表就抽象成一个类,一条数据就抽象成该类的一个对象。
- 安装‘Flask-sqlalchemy’:
pip install flask-sqlalchemy
Flask-SQLAlchemy的使用
- 初始化和设置数据库配置信息:
- 使用flask_sqlalchemy中的SQLAlchemy进行初始化:
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
- 设置配置信息,在config.py文件中添加以下配置信息:
* dialect+driver://username:password@host:port/database *
DIALECT = 'mysql'
DRIVER = 'mysqldb'
USERNAME = 'root'
PASSWORD = 'Gao123456'
HOST = 'localhost'
PORT = '3306'
DATABASE = 'db_demo1'
SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = False
- 在主app文件中添加配置文件(config.py)
- 配置文件和主app文件在同一目录下:
import config
app.config.from_object(config)
- 配置文件来自于其他目录(./config/config.py)
目录需要包含一个叫做 __init__.py 的文件
from config.config
app.config.from_object(config.config_demo1)
- 测试
db.creat_all()
如果没有报错,说明配置没有问题,如果有错误,可以根据错误进行修改
SQLAlchemy模型与表映射
- 模型需要继承自‘db.Model’,然后需要映射到表中的属性,必须写成‘db.Column’的数据类型。
- 数据类型:
- db.Integer:int
- db.String:varchar()
- db.Text:text
- 其他参数:
- Primary_key:代表将这个字段设置为主键
- autoincrement:代表这个主键为自增长
- nullable:代表这个字段是否为空,默认为空。可以将这个值设置为‘False’,那么在数据库中,这个值就不能为空了。
- 最后需要调用‘db.create_all()’来讲模型真正的创建到数据库中。
class Article(db.Model):
__tablename__ = 'article'#指定表名
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(100),nullable=False)
content = db.Column(db.Text,nullable=False)
SQLAlchemy数据增删改查
- 增加
# 增加
article1 = Article(title='aaa',content='bbb')
db.session.add(article1)
# 事务
db.session.commit()
- 查找
# 查询
article1 = Article.query.filter(Article.title == 'aaa').first()
print('title:%s' % article1.title)
print('comment:%s' % article1.content)
- 修改
# 修改
# 1.先把需要修改的数据查找出来
article1 = Article.query.filter(Article.title == 'aaa').first()
# 2.将查找到的数据所要修改的地方进行修改
article1.title = 'new title'
# 3.做事务提交
db.session.commit()
- 删除
# 删除
# 1.把需要删除的数据查找出来
article1 = Article.query.filter(Article.title == 'aaa').first()
# 2.删除数据
db.session.delete(article1)
# 3.做事务提交
db.session.commit()
Flask_SQLAlchemy外键及其关系
- 外键:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.String(100),nullable=False)
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(100),nullable=False)
content = db.Column(db.Text,nullable=False)
author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
author = db.relationship('User',backref=db.backref('articles'))
-
author = db.relationship('User',backref=db.backref('articles'))
解释:
- 给‘Article’这个模型添加一个‘author’属性,可以访问这篇文章的作者的数据,就像访问普通模型一样
- ‘backref’是定义反向引用,可以通过‘User.articles’访问这个模型所写的所有文章
- 多对多关系
- 多对多的关系,要通过一个中间表进行关联
- 中间表,不能通过‘class’的方式创建,只能通过‘db.Table’的方式创建
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(100),nullable=False)
tags = db.relationship('Tag',secondary='article_tag',backref=db.backref('articles'))
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(100),nullable=False)
article_tag = db.Table('article_tag',
db.Column('article_id',db.Integer,db.ForeignKey('article.id'),primary_key=True),
db.Column('tag_id',db.Integer,db.ForeignKey('tag.id'),primary_key=True)
)
- 设置关联:
tags = db.relationship('Tag',secondary='article_tag',backref=db.backref('articles'))
- 访问和添加数据可以通过一下方式操作:
- 添加数据
article1 = Article(title='iPhone')
article2 = Article(title='iPad')
tag1 = Tag(name='Easy')
tag2 = Tag(name='Good')
article1.tags.append(tag1)
article1.tags.append(tag2)
article2.tags.append(tag1)
article2.tags.append(tag2)
db.session.add(article1)
db.session.add(article2)
db.session.add(tag1)
db.session.add(tag2)
db.session.commit()
- 访问数据
article1 = Article.query.filter(Article.title =='iPhone').first()
tags = article1.tags
for tag in tags:
print (tag.name)
Flask_script的介绍与安装
- Flask-script:其作用是可以通过命令行的形式来操作FLask。例如通过命令跑一个开发版本的服务器,设置数据库,定时任务等。
- 安装:进入到虚拟环境中,使用一下命令安装:
pip install flask-script
- 如何直接在主‘manager.py’中写命令,那么在终端只需要
python manager.py command_name
就可以了。 - 如果把一些命令集中在一个文件中,那么在终端就需要输入一个父命令,比如
python manager.py db init
- 例子:
from flask_script import Manager
from flask_script_demo import app
from db_script import DBmanager
manager = Manager(app)
@manager.command
def runserver():
print('The server is running!')
manager.add_command('db',DBmanager)
if __name__ == '__main__':
manager.run()
- 有子命令的例子:
from flask_script import Manager
DBmanager = Manager()
@DBmanager.command
def init():
print('数据库初始化完成')
@DBmanager.command
def migrate():
print('数据库迁移成功')
分开‘models’以及解决循环引用:
- 分开models的目的:为了让代码更加方便的管理
- 如何解决循环引用:把‘db’放在一个单独的文件中,切断循环引用的线条就可以了
# models_sep.py
from flask import Flask
from models import Article
from exts import db
# models.py
from exts import db
class Article(db.Model):
pass
# exts.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
db.init_app(app)
Flask-Migrate的介绍与安装
- 介绍:因为采用
db.create_all
在后期修改字段的时候,不会自动的映射到数据库中,必须删除表,然后重新运行db.create_all
才会重新映射,这样不符合我们的需求。因此flask—migrade就是为了解决这个问题,它可以在每次修改模型后,将修改的内容映射到数据库中 - 安装:进入虚拟环境使用一下命令安装:
pip install flask-migrate
- 使用‘flask-migrate’必须借助‘flask-script’,这个包的‘MigrateCommand’中包含的所有与数据库相关的命令
- ‘flask-migrate’相关的命令:
- python manager.py db init:初始化一个迁移脚本环境,只需要执行一次
- python manager.py migrate:将模型生成迁移文件,只要模型更改了,就需要执行一边这个命令
- python manager.py db upgrade:将迁移文件真正的映射到数据库中,每次运行了
migrate
命令后,就要运行此命令
- 注意点:需要映射到数据库的模型,都要导入到manager.py中,如果没有导入,就不会映射到数据库中
- manager.py相关代码:
from flask_script import Manager
from migrate_demo import app
from flask_migrate import Migrate,MigrateCommand
from exts import db
from models import Article
# 模型 -> 迁移文件 -> 表
# init
# migrate
# upgrate
manager = Manager(app)
# 1. 要使用Flask-migrate,必须要绑定app和db
migrate = Migrate(app,db)
# 2. 把MigrateCommand命令添加到manager中
manager.add_command('db',MigrateCommand)
if __name__ == '__main__':
manager.run()
session和cookie操作
cookie的相关内容:
- cookie出现的原因:在网站中,http请求是无状态的。这就是说即使第一次和服务器连接并且登录成功后,第二次请求服务器依然不能知道当前请求的是哪个用户。cookie的出现就是为了解决这一问题,第一次登录后,服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地。当用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪一个了
- 如果服务器返回了cookie给浏览器,那么浏览器再次请求相同的服务器的时候,就会自动的吧cookie发送给服务器,这个过程用户不需要处理
- cookie是保存在浏览器中的,相对的是浏览器
session的相关内容:
- session介绍:session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但是服务器发展至今,一些session信息还是绰绰有余的
- 使用session的好处:
- 敏感数据不是直接发送回浏览器,而是发送回一个session_id,服务器将session_id和敏感数据做一个映射存储在session(服务器上)中,更加安全
- session可以设置过期时间,也保证了用户的账号安全
Flask中的session工作机制
- flask中session机制是:把敏感数据经过加密后放入session中,然后再把session存放到cookie中。下次请求的时候,再从浏览器发送过来的cookie中
读取session,然后从session中读取敏感数据并进行解密,最终获取到用户数据 - flask的这种session机制,可以节省服务器的开销,因为把所有的信息都存储到了客户端(浏览器)
- 安全是相对的,把session放到cookie中,经过加密也是比较安全的
Flask中操作session
- 使用session需要从flask中导入session,以后所有和session相关的操作都是通过这个变量来的
- 使用session需要设置‘SECRET_KEY’用来加密,并且这个‘SECRET_KEY’如果在每次服务器启动后都变化的话,那么之前的session就不能再通过当前这个‘SECRET_KEY’进行解密了
- 操作session的时候和操作字典相同
- 添加:
session['username']
- 删除:
session.pop('username')
或者del session['username']
- 获取:
session.get('username')
- 清除所有session:
session.clear()
- 设置session的过期时间
- 如果没有指定session的过期时间,那么默认是浏览器关闭后就自动结束
- 如果设置了session的permanent属性为True,那么过期时间默认为31天
- 可以通过设置:
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)
来更改过期时间
装饰器
- 装饰器实际上就是一个函数,有两个特别之处
- 参数是一个函数
- 返回值是一个函数
- 装饰器的使用是通过@符号,放在函数的上面
- 装饰器中定义的函数,要使用args,*kwargs两个参数组合
- 需要使用functools.wraps在装饰器中的函数上把传进来的函数进行一个处理,这样就不会丢失其原来name等属性
from functools import wraps
def my_log(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('hello world!')
func(*args, **kwargs)
return wrapper
@my_log
def run():
print('run')
@my_log
def add(a, b):
c = a + b
print('c = %s' % c)
run()
add(1, 3)
print(run.__name__)
知识点补充
get请求和post请求
- get请求
- 使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这时候使用get请求
- 传参:get请求传参是放在url中,并且是通过'?'的形式来指定key和value的
- post请求
- 使用场景:如果要对服务器产生影响,那么使用post请求
- 传参:post请求传参不是放在url中,是通过‘form data’的形式发送给服务器的
get和post请求获取参数
- get请求是通过
flask.request.args
来获取的 - post请求是通过
flask.request.form
来获取的 - post请求在模版中要注意:
- input标签中要写name来标示这个value的key,方便后台获取
- 在写form表单的时候,要指定
method='post'
,并且要指定action="{{ url_for('login') }}"
- 示例代码
<form action="{{ url_for('login') }}" method="POST">
<table>
<tbody>
<tr>
<td>用户名:</td>
<td><input type="text" placeholder="请输入用户名" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" placeholder="请输入密码" name="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="登录"></td>
</tr>
</tbody>
</table>
</form>
保存全局变量的g属性(g:global)
- g对象是专门用来保存用户的数据的
- g对象在一次请求中,代码所有的地方都是可以使用的
钩子函数(hook)
- before_request:
- 在请求之前执行
- 是在视图函数执行之前执行的
- 这个函数只是一个装饰器,它可以把需要设置为钩子函数的代码放到视图函数执行之前执行
- 代码示例:
@app.before_request
def my_before_request():
if session.get('username'):
g.username = session.get('username')
- context_processor:
- 上下文处理器应该返回一个字典,字典中的‘key’会被模版当作变量来渲染
- 上下文处理器中返回的字典,在所有页面中都是可用的
- 被这个装饰器修饰的钩子函数,必须要返回一个字典,即使为空也要返回
- 代码示例:
@app.context_processor
def my_context_processor():
return {'username':'Jason'}
实战演练
项目结构搭建
- zlktqa.py:主app文件
- config.py:配置文件,设置数据库、密钥、debug等等
- exts.py:解决循环引用
- manager.py:flask_script命令应用
- models.py:分开models
导航条构建
父模版抽离
{% extends 'base.html' %}
{% block title %}首页{% endblock %}
{% block main %}这是首页{% endblock %}
登录页面完成和注册页面完成
pass
用户模型创建
- 创建模型User
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
telephone = db.Column(db.String(11), nullable=False)
username = db.Column(db.String(50), nullable=False)
password = db.Column(db.String(100), nullable=False)
- 进入虚拟环境,利用flask-script创建数据库表
python manage.py db init
python manage.py db migrate
python manage.py db upgrade
注册功能完成
- 注册功能未判断输入是否为空以及是否符合相应格式
- 密码在数据库中为明文
登录功能完成
待完善
登录和注销状态切换
利用钩子函数context_processor
发布问答界面完成
登录限制
在未登录状态下,访问发布问答页面时,要登录
from functools import wraps
from flask import session, redirect
# 登录限制的装饰器
def login_required(func):
@wraps(func)
def wrapper(*args, **kwargs):
if session.get('user_id'):
return func(*args, **kwargs)
else:
return redirect('login')
return wrapper
# 发布问答
@app.route('/question/')
@login_required
def question():
if request.method == 'GET':
return render_template('question.html')
else:
pass
发布问答功能完成
# 发布问答
@app.route('/question/', methods=['GET', 'POST'])
@login_required
def question():
if request.method == 'GET':
return render_template('question.html')
else:
title = request.form.get('title')
content = request.form.get('content')
question = Question(title=title, content=content)
user_id = session.get('user_id')
user = User.query.filter(User.id == user_id).first()
question.author = user
db.session.add(question)
db.session.commit()
return redirect(url_for('index'))
密码保护
from exts import db
# 导入转换密码需要的库
from werkzeug.security import generate_password_hash, check_password_hash
# 用户模型
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
telephone = db.Column(db.String(11), nullable=False)
username = db.Column(db.String(50), nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
# 定义函数,需要用属性时,可以用函数代替
@property
def password(self):
return self.password_hash
# 转换密码为hash存入数据库
@password.setter
def password(self, row_password):
self.password_hash = generate_password_hash(row_password)
# 检查密码
def check_password(self, row_password):
return check_password_hash(self.password_hash, row_password)
# 登录
@app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
telephone = request.form.get('telephone')
password = request.form.get('password')
user = User.query.filter(User.telephone == telephone).first()
if user:
if user.check_password(password):
session['user_id'] = user.id
session.permanent = True
return redirect(url_for('index'))
else:
return u'密码错误!'
else:
return u'用户不存在,请注册后登录!'
# 注册
@app.route('/regist/', methods=['GET', 'POST'])
def regist():
if request.method == 'GET':
return render_template('regist.html')
else:
telephone = request.form.get('telephone')
username = request.form.get('username')
password_1 = request.form.get('password_1')
password_2 = request.form.get('password_2')
# 手机号码验证,如果被注册,就不能再注册了
user = User.query.filter(User.telephone == telephone).first()
if user:
return u'改手机号已被注册,请更换手机号码!'
else:
# password_1和password_2要一样才可以
if password_1 != password_2:
return u'两次密码不一样,请核对后再填写!'
else:
user = User(telephone=telephone, username=username, password=password_1)
db.session.add(user)
db.session.commit()
# 如果注册成功,就让页面跳转到登录界面
return redirect(url_for('login'))
定时任务Celery
- 安装celery
pip install celery
- 通过Homebrew安装消息代理Redis
brew install redis
- 通过指令
redis-server
启动Redis(关闭redis:redis-cli shutdown
) - 通过终端进入celery文件所在目录,执行以下命令开启工作池
celery -A celery_task worker --loglevel=info
celery_task代码如下所示
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from celery import Celery
from celery import platforms
from crawler import getdata
import datetime
import time
# 用于开启root也可以启动celery服务,默认是不允许root启动celery的
platforms.C_FORCE_ROOT = True
# 创建一个celery实例,传递进去的第一个参数必须是本文件的文件名celery,指定broker为本机redis6380服务
celery = Celery('celery_task', broker='redis://localhost:6379/0')
@celery.task
def task(h=1, m=0):
while True:
while True:
now = datetime.datetime.now()
if now.hour == h and now.minute == m:
break
time.sleep(60)
getdata()
print('执行完毕!')