├── Django Session 问题 ├── Django使用redis做缓存层.md ├── Flask-RESTfulAPI ├── README.md └── RESTfulAPI.py ├── LICENSE ├── Pycharm-Remoter ├── README.md └── 使用Pycharm进行远程代码编写.docx ├── README.md ├── SVN模块 ├── README.md └── SVN接口模块.py ├── SendMail ├── Django 发送邮件配置.md ├── README.md ├── 发送图片.py └── 通过SSL发送邮件.py ├── apache+django 后台样式错误.md ├── django 返回 html 函数的区别.md ├── django使用redis+celery异步执行任务.md └── django使用定时更新任务.md /Django Session 问题: -------------------------------------------------------------------------------- 1 | # Django 中的session的一些小小的坑~! 2 | 3 | ### 什么是session? 4 | http://www.jianshu.com/p/5dbd86ae6203 //大神的解释如此简单~! 5 | http://www.cnblogs.com/liruixin/p/6275767.html //session的配置 6 | 7 | django中session默认保存位置是:Mysql数据库中的django.session数据库中 8 | 9 | 10 | session设置有效时间: 11 | ```python 12 | SESSION_SAVE_EVERY_REQUEST = True // 是否每次请求都保存Session,默认修改之后才保存 13 | SESSION_COOKIE_AGE = 60*30 // 保存30分钟 14 | # SESSION_EXPIRE_AT_BROWSER_CLOSE = False // 关闭浏览器后依然有效 15 | # SESSION_COOKIE_DOMAIN = "http://192.168.0.220:4908" // 生效的站点 16 | # SESSION_COOKIE_NAME = "websession" // cookies中session名 17 | ``` 18 | 19 | 20 | 如果session没有自动删除? 21 | manage.py clearsessions 22 | 23 | 为什么没有自动删除? 24 | 1. 用户没有退出登录 25 | 2. 直接关闭浏览器 26 | 27 | -------------------------------------------------------------------------------- /Django使用redis做缓存层.md: -------------------------------------------------------------------------------- 1 | ### Django使用redis做缓存层 2 | 3 | 参考文档: 4 | http://django-redis-chs.readthedocs.io/zh_CN/latest/# //官方 5 | http://yshblog.com/blog/156 //案例实践 6 | http://www.runoob.com/redis/redis-tutorial.html //redis使用教程 7 | 8 | 注意: 9 | 1. 该教程的前提是已经安装了redis服务,并正常运行,没有安装的请自行百度 10 | 2. 缓存层使用了redis,如果有多个服务 需要使用到redis,请先停止,然后再测试,要不很麻烦。!!! 11 | 12 | 13 | 版本: 14 | django:1.9 15 | redis-server:3.0.6 16 | python:2.7 17 | django-redis:4.8.0 18 | python redis:2.10.5 19 | 20 | 21 | ### step1:安装redis相关插件 22 | ```bash 23 | pip install django-redis 24 | pip install redis 25 | ``` 26 | 27 | 28 | ### step2:配置setting文件(还有其他参数,请看官方文档) 29 | ``` 30 | CACHES = { 31 | "default": { 32 | "BACKEND": "django_redis.cache.RedisCache", 33 | "LOCATION": "redis://localhost:6379/1", //这个很重要,1是代表数据库名,如果之前使用异步需要redis的,建议分开使用 34 | "OPTIONS": { 35 | "CLIENT_CLASS": "django_redis.client.DefaultClient", 36 | # "PASSWORD": "mysecret" 这个是redis登录密码 37 | } 38 | } 39 | } 40 | ``` 41 | 42 | 43 | ### step3:测试通过django-redis写入数据到redis中 44 | ```bash 45 | [root@9683705d680e operation]# python manage.py shell //注意我们测试的时候用manage shell,因为这个是已经默认好环境的了 46 | >>> from django.core.cache import cache //导入模块 47 | >>> cache.set("test", "test11111") //保存数据进redis中 48 | True 49 | >>> cache.get("test") //从redis中取出数据 50 | 'test11111' 51 | >>> 52 | ``` 53 | 54 | 55 | ### step4:查看redis是否有数据 56 | ``` 57 | [root@9683705d680e ~]# redis-cli //连接redis,怎么操作请自行百度 58 | 127.0.0.1:6379> select 1 //选择数据库,前面是设置为1,即选择1 59 | OK 60 | 127.0.0.1:6379> keys * 61 | 1) ":1:test" //这个是刚刚保存的数据 62 | 127.0.0.1:6379> 63 | ``` 64 | 65 | 66 | ### step5:测试没有问题,就可以写代码(views.py文件中写,或自定义模块导入,随便吧) 67 | ```python 68 | from django.core.cache import cache //导入模块 69 | class RequestImage(View): 70 | def get(self, request): 71 | key = "apache" 72 | if cache.has_key(key): 73 | data = cache.get(key) //找到数据就返回值 74 | else: //找不到数据,就重新创建数据,并返回数据(这个逻辑很重要) 75 | data = "zabbxi-ssh-test" 76 | cache.set(key, data) 77 | return HttpResponse(data) //就是有没有,都返回。 78 | ``` 79 | 80 | 81 | ### step6:返回到前端显示(部分代码) 82 | ```javascript 83 | function select(){ 84 | $.get("/requestimage/", function(data){ 85 | alert(data); //返回一个字典 86 | for (var i in data){ 87 | $("#modules").append(""); 88 | } 89 | }); 90 | } 91 | ``` 92 | 93 | 94 | -------------------------------------------------------------------------------- /Flask-RESTfulAPI/README.md: -------------------------------------------------------------------------------- 1 | ## Flask RESTfulAPI 简单介绍 2 | 3 | #### 描述:通过Flask可以写出一个API接口,flask自带有安全认证机制,我们可以直接使用这个机制,让你的接口接近安全 4 | 5 | **环境:** 6 | 7 | 1. Python 2.7 8 | 2. Flask * 9 | 3. Linux Centos6.5 10 | 11 | 12 | **安装:** 13 | 14 | pip install flask 15 | 16 | pip install flask-httpauth 17 | 18 | 19 | **注意:** 20 | 21 | 1. 代码文件中只有对GET/POST/PUT三种模式和一种安全机制进行基础代码示例,详情可以直接参考官方文档 22 | 2. 文件中代码有注释,单一调试请去掉注释即可。 23 | 24 | 25 | 26 | **参考文档及一些文章:** 27 | 28 | 1. RESTful API中文版:[http://www.pythondoc.com/flask-mega-tutorial/index.html](http://www.pythondoc.com/flask-mega-tutorial/index.html) 29 | 30 | 2. RESTful API官方版本:[http://flask-restless.readthedocs.io/en/stable/api.html](http://flask-restless.readthedocs.io/en/stable/api.html) 31 | 32 | 3. RESTful API快速入门:[http://www.cnblogs.com/kaituorensheng/p/4645080.html](http://www.cnblogs.com/kaituorensheng/p/4645080.html) 33 | 34 | 4. Flask官方文档:[http://www.pythondoc.com/flask-mega-tutorial/index.html](http://www.pythondoc.com/flask-mega-tutorial/index.html) 35 | 36 | -------------------------------------------------------------------------------- /Flask-RESTfulAPI/RESTfulAPI.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # author:eycode 3 | # 该文件用于提供测试接口 4 | # Flask + API模块 5 | 6 | # 在本代码案例中必须安装两个模块: 7 | # flask模块:pip install flask 8 | # http认证模块(flask-httpauth):pip install flask-httpauth 9 | 10 | # 参考地址: 11 | # RESTful API中文版:http://www.pythondoc.com/flask-mega-tutorial/index.html 12 | # RESTful API快速入门:http://www.cnblogs.com/kaituorensheng/p/4645080.html 13 | # RESTful API官方版本:http://flask-restless.readthedocs.io/en/stable/api.html 14 | # Flask官方:http://www.pythondoc.com/flask-mega-tutorial/index.html 15 | 16 | from flask import Flask, jsonify 17 | 18 | # 简单版本: 19 | # app = Flask(__name__) 20 | 21 | # @app.route('/') 22 | # def index(): 23 | # return "Hello Python" 24 | 25 | # if __name__ == "__main__": 26 | # app.run(debug=True) 27 | # 或 28 | # app.run(host='0.0.0.0',port=9000) 29 | 30 | 31 | 32 | # 测试:打开浏览器输入:http://127.0.0.1:5000 33 | # 返回结果: 34 | # Hello Python 35 | 36 | 37 | 38 | # 简单分析: 39 | # 第9行:app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递__name__。 40 | # 让flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和模板文件的目录 41 | 42 | # 第11~13行:使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上。 43 | # 处理URL和视图函数的关系的程序就是路由,这里的视图函数就是hello_world。 44 | 45 | # 第16行:执行app.run就可以启动服务了。默认Flask只监听虚拟机的本地127.0.0.1这个地址,端口为5000。 46 | # 而我们对虚拟机做的端口转发端口是9000,所以需要制定host和port参数,0.0.0.0表示监听所有地址,这样就可以在本机访问了。 47 | # 服务器启动后,会调用werkzeug.serving.run_simple进入轮询,默认使用单进程单线程的werkzeug.serving.BaseWSGIServer处理请求, 48 | # 实际上还是使用标准库BaseHTTPServer.HTTPServer,通过select.select做0.5秒的“while TRUE”的事件轮询。 49 | # 当我们访问“http://127.0.0.1:9000/”,通过app.url_map找到注册的“/”这个URL模式,就找到了对应的hello_world函数执行,返回“hello world!”,状态码为200。 50 | # 如果访问一个不存在的路径,如访问“http://127.0.0.1:9000/a”,Flask找不到对应的模式,就会向浏览器返回“Not Found”,状态码为404 51 | 52 | 53 | 54 | 55 | # 构建一个简单的入口 56 | # app = Flask(__name__) 57 | 58 | # tasks = [ 59 | # { 60 | # 'id':1, 61 | # 'name':"eycode", 62 | # 'age':23, 63 | # 'sex':"男" 64 | # }, 65 | # { 66 | # 'id':2, 67 | # 'name':"imay", 68 | # 'age':1, 69 | # 'sex':'女' 70 | # } 71 | # ] 72 | 73 | # @app.route("/api/v1.0/tasks", methods=['GET']) 74 | # def _tasks(): 75 | # return jsonify({'tasks':tasks}) 76 | 77 | # if __name__ == "__main__": 78 | # app.run(host='0.0.0.0', port=9000, debug=True) 79 | 80 | 81 | # 打开浏览器输入:http://127.0.0.1:9000/api/v1.0/tasks 82 | # 返回结果: 83 | # { 84 | # "tasks": [ 85 | # { 86 | # "age": 23, 87 | # "id": 1, 88 | # "name": "eycode", 89 | # "sex": "\u7537" 90 | # }, 91 | # { 92 | # "age": 1, 93 | # "id": 2, 94 | # "name": "imay", 95 | # "sex": "\u5973" 96 | # } 97 | # ] 98 | # } 99 | 100 | 101 | 102 | 103 | # GET方式递交参数,返回值 104 | # from flask import abort, make_response 105 | 106 | # app = Flask(__name__) 107 | 108 | # tasks = [ 109 | # { 110 | # 'id':1, 111 | # 'name':"eycode", 112 | # 'age':23, 113 | # 'sex':"男" 114 | # }, 115 | # { 116 | # 'id':2, 117 | # 'name':"imay", 118 | # 'age':23, 119 | # 'sex':"男" 120 | # }, 121 | # { 122 | # 'id':3, 123 | # 'name':"benet", 124 | # 'age':23, 125 | # 'sex':"男" 126 | # } 127 | # ] 128 | 129 | # @app.route('/api/v1.0/', methods=['GET']) 130 | # def get_tasks(task_id): 131 | 132 | # # 当传进的id是多少就读取字典的哪个部分 133 | # task = filter(lambda t:t['id'] == task_id, tasks) 134 | # if len(task) == 0: 135 | # """判断是否存在,如果不存在,则返回404页面""" 136 | # abort(404) 137 | # return jsonify({'task':task[0]}) 138 | 139 | # # 自定义404信息(以json的方式返回数据) 140 | # @app.errorhandler(404) 141 | # def not_found(error): 142 | # return make_response(jsonify({'error': 'Not found'}), 404) 143 | 144 | # if __name__ == "__main__": 145 | 146 | # # 关闭调试 147 | # app.run(debug=False) 148 | 149 | 150 | 151 | # 测试:http://127.0.0.1:5000/api/v1.0/1 152 | # 返回结果: 153 | # { 154 | # "task": { 155 | # "age": 23, 156 | # "id": 1, 157 | # "name": "eycode", 158 | # "sex": "\u7537" 159 | # } 160 | # } 161 | 162 | # 测试: http://127.0.0.1:5000/api/v1.0/5 163 | # 返回结果: 164 | # { 165 | # "error": "Not found" 166 | # } 167 | 168 | 169 | 170 | 171 | # 通过Post方式提交数据 172 | # from flask import request 173 | 174 | # app = Flask(__name__) 175 | 176 | # tasks = [ 177 | # { 178 | # 'id':1, 179 | # 'name':"eycode", 180 | # 'age':23, 181 | # 'sex':"男" 182 | # }, 183 | # { 184 | # 'id':2, 185 | # 'name':"imay", 186 | # 'age':23, 187 | # 'sex':"男" 188 | # }, 189 | # { 190 | # 'id':3, 191 | # 'name':"benet", 192 | # 'age':23, 193 | # 'sex':"男" 194 | # } 195 | # ] 196 | 197 | 198 | # @app.route('/api/v1.0/tasks', methods=['POST']) 199 | # def create_task(): 200 | # if not request.json or not 'title' in request.json: 201 | # abort(404) 202 | 203 | # task = { 204 | # 'id': tasks[-1]['id'] + 1, 205 | # 'title': request.json['title'], 206 | # 'sex': request.json.get('sex', ""), 207 | # 'done': False 208 | # } 209 | # tasks.append(task) 210 | # return jsonify({'task':task}), 201 211 | 212 | # if __name__ == "__main__": 213 | # app.run(debug=False) 214 | 215 | 216 | # 测试:curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000//api/v1.0/tasks 217 | # 一些参数: 218 | # -i :显示信息 219 | # -H:指定http头 220 | # -X:提交方式不区分大小写 221 | # -d:字典 222 | 223 | 224 | # API安全性使用 225 | from flask.ext.httpauth import HTTPBasicAuth 226 | from flask import abort, make_response 227 | auth = HTTPBasicAuth() 228 | 229 | @auth.get_password 230 | def get_password(username): 231 | if username == "eycode": 232 | return 'python' 233 | return None 234 | 235 | @auth.error_handler 236 | def unauthorized(): 237 | return make_response(jsonify({'error':'Unauthorized access'}), 403) 238 | 239 | tasks = [ 240 | { 241 | 'id':1, 242 | 'name':"eycode", 243 | 'age':23, 244 | 'sex':"男" 245 | }, 246 | { 247 | 'id':2, 248 | 'name':"imay", 249 | 'age':23, 250 | 'sex':"男" 251 | }, 252 | { 253 | 'id':3, 254 | 'name':"benet", 255 | 'age':23, 256 | 'sex':"男" 257 | } 258 | ] 259 | 260 | app = Flask(__name__) 261 | 262 | @app.route('/api/v1.0/tasks', methods=['GET']) 263 | @auth.login_required 264 | def get_tasks(): 265 | return jsonify({'tasks': tasks}) 266 | 267 | if __name__ == "__main__": 268 | app.run() 269 | 270 | 271 | # 测试:http://127.0.0.1:5000/api/v1.0/tasks 272 | # 返回结果: 273 | # { 274 | # "error": "Unauthorized access" 275 | # 276 | 277 | # 测试:curl -u eycode:python -i http://localhost:5000/api/v1.0/tasks 278 | # 一些参数: 279 | # -u:用户名:密码 280 | 281 | # 返回结果: 282 | # { 283 | # 'id':1, 284 | # 'name':"eycode", 285 | # 'age':23, 286 | # 'sex':"男" 287 | # }, 288 | # { 289 | # 'id':2, 290 | # 'name':"imay", 291 | # 'age':23, 292 | # 'sex':"男" 293 | # }, 294 | # { 295 | # 'id':3, 296 | # 'name':"benet", 297 | # 'age':23, 298 | # 'sex':"男" 299 | # } 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 可乐 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pycharm-Remoter/README.md: -------------------------------------------------------------------------------- 1 | ## 使用Pycharm进行远程代码编写 2 | 3 | ### 写在前面: 4 | 5 | ##### 如题,为什么要这样做? 6 | 7 | 1. 像作者,有自己的Linux服务器,并在上面已经部署了Docker之类的环境,而本地的Win系统也不满足代码编写环境(同样有人说Win上也有Python多环境支持,但是我想说的是,没有必须折腾,等你搭建好多环境支持,我都已经写完一个项目了。) 8 | 9 | 2. 统一管理代码,同时支持不同电脑写代码,例如我在家写好代码上传到服务器上,回到公司我打开IDE直接同步就可以使用了,方便(有人说为什么不用Git或SVN?统一回复,根据实际情况来用,作者也用svn或Git,谁用谁知道) 10 | 11 | 3. 有利于快速部署,假如你远程服务器上Docker,写好代码,调试正常,直接Docker生成镜像提交到生产环境 12 | 13 | 4. 值得注意的是,不具备版本管理功能,不像Git或SVN那样的功能,要慎重考虑情况 14 | 15 | 5. 如果是土豪,就用MacBook吧。 16 | 17 | 18 | #### 描述: 19 | 20 | > Pycharm是一个非常好的IDE,根据不同环境有着不同的功能,缺点就是-----耗资源,好耗资源,很耗资源!!!!,如果是老机器可以使用Sublime 轻量IDE,功能强大 21 | 22 | #### 环境: 23 | 24 | 1. Pycharm专业版(一定要专业版),没有专业版?某度下就有了,你懂的~ 25 | 26 | 2. Linux + Window混合环境,Window安装IDE,代码运行环境Linux 27 | 28 | 3. Python* / 各种语言都可以 29 | 30 | 31 | #### 相关文档: 32 | 33 | Pycharm官方下载地址:[http://www.jetbrains.com/pycharm/download/](http://www.jetbrains.com/pycharm/download/) 34 | 35 | 第三方下载地址(破解+中文):[http://www.jb51.net/softs/541909.html](http://www.jb51.net/softs/541909.html) 36 | 37 | > 建议是官方,然后找注册码。 38 | 39 | **推荐:官方下载,购买正版。一个好的作品值得大家的支持!!!** -------------------------------------------------------------------------------- /Pycharm-Remoter/使用Pycharm进行远程代码编写.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kele59/python-django-learning/a92961ab12e764f308ae29447caa69061418fd54/Pycharm-Remoter/使用Pycharm进行远程代码编写.docx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-django-learning 2 | - python 和 django 学习资料,书籍,文章,以及实战项目等等 3 | - [仿照慕课网搭建的在线编程学习平台](https://github.com/zaxlct/imooc-django) 4 | - [基于flask框架开发的微信小程序后端,用于构建小程序商城](https://github.com/bodanli159951/mini-shop-server) 5 | - QQ 群 163801325 6 | 7 | ## 项目贡献规范 8 | - 务必先阅读 [中文文案排版指北](https://github.com/mzlogin/chinese-copywriting-guidelines) 9 | - 请遵守上面规范里的格式和排版 10 | 11 | 12 | ## Python 基础 13 | 14 | 当你学到 Django 的时候,我们默认你已经有了 Python 基础。如果你没有 Python 基础,或者认为自己还需要在 Python 基础上多花一些时间,你可以选择从以下三本书着手。 15 | 16 | * [《Python编程 从入门到实践》](https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/B01ION3VWI/ref=sr_1_1?ie=UTF8&qid=1498793018&sr=8-1&keywords=python+crash+course) ([Python Crash Course: A Hands-On, Project-Based Introduction to Programming](https://www.amazon.com/Python-Crash-Course-Hands-Project-Based/dp/1593276036/ref=sr_1_1?ie=UTF8&qid=1498793322&sr=8-1&keywords=python+crash+course))这本书的作者就是 Django 项目的维护者之一。本书在学习 Python 基础的同时,可以学到一些 Python 的最佳实践(当然谈到最佳实践,有更多的进阶书籍的选择)。推荐本书的另一个原因是书籍质量不错,在美国亚马逊的 Python programming 排行榜上荣获“Best seller“,194个读者综合评分为4.4的高分(满分5分)。 17 | 18 | * [《"笨办法"学Python(第3版)》](https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/B00P6OJ0TC/ref=sr_1_1?ie=UTF8&qid=1498793029&sr=8-1&keywords=python+%E7%AC%A8%E5%8A%9E%E6%B3%95) ([Learn Python the Hard Way](https://learnpythonthehardway.org/book/)) 这本书简称“LPHW”,是经久不衰的 Python 入门书。本书强调的是肌肉记忆,强调的是编程犹如弹吉他,需要亲手实践、加强肌肉记忆。如果你对编程也没有太多概念,这本书会比较轻松的带你入门,增强你的编程自信心。 19 | 20 | * [《Python 基础教程》](https://www.amazon.cn/%E5%9B%BE%E7%81%B5%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E4%B8%9B%E4%B9%A6-Python%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B-%E8%B5%AB%E7%89%B9%E5%85%B0/dp/B00KAFX65Q/ref=sr_1_1?ie=UTF8&qid=1508737548&sr=8-1&keywords=python+novice)([Beginning Python: From Novice to Professional](https://www.amazon.cn/Beginning-Python-From-Novice-to-Professional-Hetland-Magnus-Lie/dp/1484200292/ref=sr_1_4?ie=UTF8&qid=1508737548&sr=8-4&keywords=python+novice)) 如果在这三本中选一本必看的基础书,个人更偏好、也更推荐这一本。作者对基础知识的讲解清晰明了,内容简单但是并不肤浅。讲解过程通畅,基本不存在费解的情况。代码小片段实例比比皆是,马上就可以动手实践来理解概念,可以让人更容易记得住,学习的效果也是相当好。较深的概念有延展的接口,提供方向供后期自己去扩展。值得一提的是,目前这本书中文翻译仍然是[2009年英文版的 Python 2.7](https://www.amazon.com/Beginning-Python-Novice-Professional-Experts/dp/1590599829/ref=sr_1_2?ie=UTF8&qid=1508738718&sr=8-2&keywords=beginning+Python%3A+from+novice+to+professional),而今年(2017年)4月Apress出版社继续推出了[该书最新的第三版](https://www.amazon.com/Beginning-Python-Professional-Magnus-Hetland/dp/1484200292/ref=sr_1_1?ie=UTF8&qid=1508738718&sr=8-1&keywords=beginning+Python%3A+from+novice+to+professional),已经使用 Python 3 的版本(暂无中文版)。作者 Magnus Lie Hetland 在 2006 年开始写作第一版至今,时隔11年还能继续推出最新版,而且内容质量靠谱,实在难能可贵。 21 | 22 | 如果你觉得看视频入门更适合自己,那么我推荐: 23 | [Python3 入门与进阶](https://coding.imooc.com/class/136.html) 24 | (付费课程,但是质量非常高,具体可以看用户评价) 25 | 26 | ## Django 与 Python 开发环境问题 27 | 28 | **注意:[目前在维护 Django 版本](https://en.wikipedia.org/wiki/Django_(web_framework))为:Django 1.8(长期支持版,LTS),Django 1.10,Django 1.11(最新版,长期支持版,LTS,也是最后一个支持 Python2的版本)。** 29 | 30 | 如果学习资料是这些版本以前的版本,比如 Django 1.7,则不建议再学习已经过时的资料。对于书籍是否已经过时,Two Scoops 的作者 Daniel R. Greenfeld(也是Django的项目维护者)有一个书籍清单供参考([Current Django Books](https://www.twoscoopspress.com/pages/current-django-books))。 31 | 32 | Django 的版本以及 Python 开发环境至关重要,请在最开始学习 Django 的时候就引起重视。由于 Python、Django以及其他第三方包的版本不同,有时候会产生与学习资料不一样的结果。建议学习过程中注意两点: 33 | 34 | * 为每一个项目建立虚拟环境,建立相对独立的开发环境 35 | * 严格按照学习资料的版本进行开发。注意是 Python 2 还是 Python 3,Django 的版本、以及第三方包的版本号。 36 | 37 | 38 | 39 | ## Django 基础 40 | 41 | ### 1. 视频 42 | 43 | 推荐使用慕课网的两门免费在线视频课程作为入门: 44 | 45 | * [django初体检](http://www.imooc.com/learn/458) 46 | * [django入门与实践](http://www.imooc.com/learn/790) 47 | 48 | 这两门课基本涵盖了 Django 最核心、同时也是最常用的部分,他们会给你建立一个 Django 的整体概念,便于消除你对 Django 的陌生感和恐惧感。 49 | 50 | 如果想进一步详细的了解 Django,有个综合性的教程名叫 51 | * [《Django 企业开发实战》](http://django-practice-book.com) 52 | 53 | 该教程包含 gitbook 电子书(免费)以及视频部分(收费)。该教程之所以比较推荐,作者是搜狐的胡阳([博客地址](https://www.the5fire.com))。阳哥长期在搜狐大量实际使用 Django,而且对源码比较熟悉,所以该教程讲得深入浅出,有不少独到的见解。 54 | 55 | ### 2. 文档 56 | 57 | 在有了视频的感性认识之后,建议马上阅读完 Django 文档的新手入门6个部分的内容,并亲手实践让代码能跑起来。文档是最权威也是最全面的 Django 参考资料。 58 | 59 | * [Getting started](https://docs.djangoproject.com/en/1.11/intro/) Django 1.11 英文原版文档的新手入门部分。 60 | * [Django 中文文档 1.8](https://wizardforcel.gitbooks.io/django-chinese-docs-18/content/) Django 1.8 的中文文档(gitbook在线书)。 61 | 62 | ### 3. 书籍与博客 63 | 64 | #### 3.1 英文 65 | 66 | * [Mastering Django: Core: The Complete Guide to Django 1.8 LTS](https://www.amazon.com/Mastering-Django-Core-Complete-Guide-ebook/dp/B01KR6F4Z2/ref=pd_sim_351_1?_encoding=UTF8&psc=1&refRID=FGPD50FMR491T393ZV8K) 这本书就是大名鼎鼎的 Django Book 的最新版本。本书前7章是连贯的学习教程,可作为入门教材,后面的章节以讲解概念为主。[《中文版的 Django Book》](http://djangobook.py3k.cn/2.0/) 使用的是 Django 1.1 版本,已经严重过时,中文版本仅供参考。作者的主页是 [djangobook.com](http://djangobook.com/)。图灵社区于今年(2017年)5月出版了这本书的[中文翻译版](http://www.ituring.com.cn/book/2401)。 67 | 68 | * [Hello Web App](https://www.amazon.com/Hello-Web-App-Tracy-Osborn/dp/0986365912?tag=tsp0c2-20) 作者之前主要从事前段工作,以一个新手的视角来完成本书。整书叙述流畅,以及跟着书完成代码。作者还有一本后续的书籍 [Hello Web App: Intermediate Concepts](https://www.amazon.com/Hello-Web-App-Intermediate-Concepts/dp/0986365920/ref=pd_bxgy_14_2?_encoding=UTF8&pd_rd_i=0986365920&pd_rd_r=9PT5VMN8HB8TZ0NH9HTP&pd_rd_w=sw4hX&pd_rd_wg=LsbKy&psc=1&refRID=9PT5VMN8HB8TZ0NH9HTP) ,内容稍微深一些。 69 | 70 | 另外有人也经常推荐以下内容,供参考: 71 | 72 | * [Tango With Django: A beginner's Guide to Web Development With Python / Django 1.9](https://www.amazon.com/gp/product/B01N91N65Y/?tag=tsp0c2-20) 值得注意的是这本书被 Two Scoops 的作者列为过时书籍。 73 | * [Django Girls Tutorial](https://tutorial.djangogirls.org/en/) Django Girl严格来说已经相当于是一个商业组织,因为该组织在卖周边、做培训,但是入门教程还是不错的,内容基本与 Tango with Django 类似。最近还推出该入门教程的[扩展部分](https://djangogirls.gitbooks.io/django-girls-tutorial-extensions/)。 74 | 75 | 76 | 77 | #### 3.2 中文 78 | 79 | * [自强学堂:Django 教程](http://code.ziqiangxuetang.com/django/django-tutorial.html) 内容详实免费。值得一提的是作者使用 Django 建站,完全是在实践 Django 的使用,而且作者从2015年至今一直在根据 Django 版本升级而更新教学内容,从最初的 Django 1.6 更新到了 Django 1.10。作者称最新版本的 Django 1.11 内容马上就要推出。 80 | 81 | 82 | * [Django Girls 教程](https://tutorial.djangogirls.org/zh/) Django Girls 的中文版,使用 Django 1.8。 83 | 84 | 85 | * [追梦人物的博客](http://zmrenwu.com/?page=5) 以 Django 1.10 为基础开发博客到部署的完整教程。 86 | 87 | 88 | 89 | ## Django 进阶 90 | 91 | ### 1. 视频 92 | 93 | 中文视频内容有很多,但是从内容的深度、广度、教学实践、教学质量来看,推荐慕课网的强力 Django 课程作为进阶必看课程。 94 | 95 | * [强力django+杀手级xadmin打造上线标准的在线教育平台](http://coding.imooc.com/class/78.html) 慕课网付费课程。虽然收费,但是课程质量上佳。内含一个 refresh 的小项目和一个较大的系统项目,涉及 Django 的内容较广,完成后可以达到上线标准。常被誉为“Django课程的良心之作”。 96 | 97 | 英文视频中,美国的 Justin Mitchel 长期专注于做 Django 培训。他的部分教学视频也放在 YouTube 上。推荐三门系列课程,分别是完成一个基本博客,增加复杂功能,到使用 django-rest-framework。内容详实,值得一看。 98 | 99 | * [Try Django 1.9](https://www.youtube.com/watch?v=yfgsklK_yFo&list=PLEsfXFp6DpzQFqfCur9CJ4QnKQTVXUsRy) 100 | * [Advancing the Blog](https://www.youtube.com/watch?v=Vp7Oa7nAXJ4&list=PLEsfXFp6DpzQB82YbmKKBy2jKdzpZKczn) 101 | * [Blog API with Django Rest Framework](https://www.youtube.com/watch?v=XMu0T6L2KRQ&list=PLEsfXFp6DpzTOcOVdZF-th7BS_GYGguAS) 102 | 103 | ### 2. 书籍 104 | 105 | 106 | * Two Scoops of Django:目前有两个版本 [Two Scoops of Django: Best Practices for Django 1.11](https://www.twoscoopspress.com/products/two-scoops-of-django-1-11) 和 [Two Scoops of Django: Best Practices for Django 1.8](https://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/0981467342/ref=pd_bxgy_14_img_3?_encoding=UTF8&pd_rd_i=0981467342&pd_rd_r=FJBAW39ZPPH73AXZQRP0&pd_rd_w=qPOZk&pd_rd_wg=caiaO&psc=1&refRID=FJBAW39ZPPH73AXZQRP0) 。这本书在 Django 的名气也是非常大,基本可以说影响过大多数 Django 开发人员(可类比的是 Flask 界的[『狗书』](https://www.amazon.cn/Flask-Web%E5%BC%80%E5%8F%91-%E5%9F%BA%E4%BA%8EPython%E7%9A%84Web%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98-%E6%A0%BC%E6%9E%97%E5%B8%83%E6%88%88/dp/B00QT2TQCG/ref=sr_1_1?ie=UTF8&qid=1508804881&sr=8-1&keywords=flask+web%E5%BC%80%E5%8F%91)作者 [Miguel Gringberg](https://blog.miguelgrinberg.com/index))。如果要进阶成为 Django 专业开发者,这本书是绕不过去的必看书籍。内容主要涵盖 Django 的最佳实践。 107 | 108 | * [Django By Example](https://www.amazon.com/Django-Example-Antonio-Mele/dp/1784391913/ref=sr_1_1?ie=UTF8&qid=1499261611&sr=8-1&keywords=django+by+example) 在进阶的课程中,本书算是不错的。虽然一些章节(比如第7章)部分代码仍然存在 bug,但是一方面作者正在该书主页不断进行代码更正,另一方面也是对中国读者最好的是,这本书已经由同在简书的 [@夜夜月](http://www.jianshu.com/u/390b6edb26a8) 进行了全书翻译:[《Django By Example》中文版](http://www.jianshu.com/c/a1fbca21af87)。 109 | 110 | * [Django Unleashed](https://www.amazon.com/Django-Unleashed-Andrew-Pinkham/dp/0321985079/ref=pd_sim_14_13?_encoding=UTF8&pd_rd_i=0321985079&pd_rd_r=FJBAW39ZPPH73AXZQRP0&pd_rd_w=qkuw5&pd_rd_wg=caiaO&psc=1&refRID=FJBAW39ZPPH73AXZQRP0) 内容覆盖较广,很多内容在其他书籍中并没有提及,比如密码的hash与加密等。但是没有实战项目。 111 | 112 | * [《Python Web 测试驱动方法》](https://www.amazon.cn/Python-Web%E5%BC%80%E5%8F%91-%E6%B5%8B%E8%AF%95%E9%A9%B1%E5%8A%A8%E6%96%B9%E6%B3%95-%E7%8F%80%E8%A5%BF%E7%93%A6%E5%B0%94/dp/B016I9T8SQ/ref=sr_1_fkmr0_3?ie=UTF8&qid=1508740219&sr=8-3-fkmr0&keywords=%E6%B5%8B%E8%AF%95%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91+django) 虽然测试驱动的开发方法(Test-Driven Development,TDD)并不是每个项目都会采用,但是测试的思想与方法还是值得去掌握。Python 作为一门动态语言,没有静态类型检测的情况下,测试的重要性就显得尤为重要。本书使用 Django 的整个开发流程作为实例,作者不仅讲了开发过程单元测试和 Selenium 测试,同时也把部署的内容也覆盖到。内容始于 Django,但不仅仅是 Django,相信使用其他框架的 Python 开发者也可以从中获益匪浅。 113 | 114 | 115 | ### 3. 博客 116 | 117 | * [Vitor Freitas: Simple is better than complex](https://simpleisbetterthancomplex.com/) 作者是旅居芬兰的巴西人,博客上有76篇关于 Python、Django 以及网络开发的文字。文章质量较高,可以邮件订阅。 118 | 119 | * [Huang Huang 的博客](https://mozillazg.github.io/) 之所以提到这个博客,主要因为作者认真写了三篇关于《High Perfomance Django》的阅读笔记:[笔记一](https://mozillazg.github.io/2015/09/high-performance-django-note-1.html)、[笔记二](https://mozillazg.github.io/2015/09/high-performance-django-note-2.html)、[笔记三](https://mozillazg.github.io/2015/09/high-performance-django-note-3.html)。从数据库优化、缓存、容灾、后台视图完善,这些一点一滴的内容都是 Django 项目开发过程中迟早会遇到的瓶颈,看一下这些内容也许就会对后面的解决方案有更深的理解。比如[『话说Django orm性能为什么比原生的mysqldb慢』](http://xiaorui.cc/2015/09/24/%E8%AF%9D%E8%AF%B4django-orm%E6%A8%A1%E5%9E%8B%E4%B8%BA%E4%BB%80%E4%B9%88%E6%AF%94%E5%8E%9F%E7%94%9F%E7%9A%84mysqldb%E6%85%A2/)这篇文章就遇到了后台报表页面打开很慢的坑,这也是完善提高 Django 性能的地方。 120 | 121 | ### 4. 开源项目 122 | - [强力django+杀手级xadmin打造上线标准的在线教育平台](https://github.com/zaxlct/imooc-django) 123 | - [《强力django+杀手级xadmin打造...》视频教程笔记](http://blog.mtianyan.cn/post/8b4c6c13.html),详细记录了每一章的步骤和重点 124 | 125 | 126 | ## Django RESTful API 127 | 128 | Django 的 REST 化主要是两个第三方包:[django-rest-framework](http://www.django-rest-framework.org/) 和 [django-tastypie](https://github.com/django-tastypie/django-tastypie)。虽然后者开发时间较早,但是最推荐的是前者,即 django-rest-framework。该框架内容更全,调试也方便。 129 | 130 | ### 1. 文档 131 | 132 | django-rest-framework 的文档分为英文和中文。英文就是原版的网站,中文有两个作者的翻译,但都是只翻译了入门部分。 133 | 134 | * [英文版文档](http://www.django-rest-framework.org/tutorial/quickstart/) 135 | * 中文文档有两个,可以对照看:[中文文档 Roy 版本](http://www.hi-roy.com/) 以及 [中文文档 Eason版本](https://whatwewant.gitbooks.io/django-rest-framework-tutorial-cn/content/index.html)。 136 | 137 | ### 2. 视频 138 | 139 | * [Vue+Django REST framework 打造生鲜电商项目](http://coding.imooc.com/class/131.html) 可能是目前中文 Django 教学视频中最好的课程,教学时间长度与内容都有相当的保证。视频作者 Bobby 详细阐述了自己对的 Django 的理解,可以让人知道多种递进式 rest API 开发方式。得益于 Bobby 精益求精的态度,个人觉得干货的程度即使与国外的内容比较也是不逞多让。另外再加上与 Vue 前端的整体交互综合开发,已经可以初步满足一个中小企业的网络解决方案。 140 | 141 | * [Build Your Own Backend REST API using Django REST Framework](https://www.udemy.com/django-python/learn/v4/overview) 作者是英国人 Mark Winterbottom,编程专业,而且讲课细致到位。 142 | 143 | 144 | * [Blog API with Django Rest Framework](https://www.youtube.com/watch?v=XMu0T6L2KRQ&list=PLEsfXFp6DpzTOcOVdZF-th7BS_GYGguAS) 仍然是之前提到的美国人 Austin Mitchel 的 YouTube 课程。 145 | 146 | ### 3. 书籍与博客 147 | 148 | * [《轻量级Django》](https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/B01M4S72G0/ref=sr_1_1?ie=UTF8&qid=1498801619&sr=8-1&keywords=%E8%BD%BB%E9%87%8F%E7%BA%A7+django) 英文版是[Lightweight Django: Using REST, WebSockets, and Backbone](https://www.amazon.com/Lightweight-Django-Using-WebSockets-Backbone/dp/149194594X/ref=sr_1_1?s=books&ie=UTF8&qid=1498801565&sr=1-1&keywords=python+lightweight),严格来说这不是一本完全讲 rest-framework 的书,而是讲解如何从传统的 Django 过渡到前后端分离 Django 。 149 | * [Building RESTful Python Web Services](https://www.amazon.com/Building-RESTful-Python-Web-Services/dp/1786462257/ref=sr_1_3?s=books&ie=UTF8&qid=1498801570&sr=1-3&keywords=python+rest) 内容涉及 Python 三大网络框架:Django,Flask以及Tornado。 150 | 151 | 152 | * [Haiiiiiyun:Django REST 框架 V3 教程](http://www.atjiang.com/tags/#djangorestframework),讲到 rest 的7门课程。 153 | 154 | 155 | ## Django 与 Vue 的结合 156 | - [《Django + Vue 单页面应用的开发环境搭建步骤》](https://www.jianshu.com/p/fe74907e16b9) 157 | - 开源项目:[hello-vue-django](https://github.com/zaxlct/hello-vue-django) 158 | 159 | ## Django 业界最新信息 160 | 161 | * [Django: Under The Hood](https://www.djangounderthehood.com/) 专注于 Django 的内容,虽然著名的 PyCon 经常请 Django 专家去演讲,但是 Django: Under The Hood 基本都是 Django 的大牛,比如2016年压轴演讲是邀请了 Instgram 的后端去讲解 INS 如何用 Django 做成了如此规模巨大的社交图片分享网站。该组织近两年的演讲内容都分享在 YouTube 上可以找到。[Django Under The Hood:YouTube地址](https://www.youtube.com/channel/UC9T1dhIlL_8Va9DxvKRowBw) 162 | * PyCon 也非常关注 Django 的发展。Django 并非完美无缺,在网络技术高速发展的今天,Django 也需要及时的进化以适应形势。在 PyCon 上,对 Django 热爱程序员们,提出了尖锐的 Django 问题,随后也有新的解决方案出来。的有代表性的演讲包括: 163 | * [Why Django Sucks - PyCon SE 2015](https://www.youtube.com/watch?v=Niq-HoraNPo) 作者提出 Django 在某些方面跟不上网络技术的发展趋势,提出了自己的三点建议。 164 | * [Reinventing Django for the Real-Time Web - PyCon 2016](https://www.youtube.com/watch?v=2sEPipctTxw&t=574s) 作者是 Django 的 Channel 部分的开发者,专注于 Socket 的包装与编程,以实现 Django 的服务器推送、异步 Socket 等功能。 165 | * [Building Dynamic Dashboards With Django and D3 - PyCon US 2016](https://www.youtube.com/watch?v=XXG-ESzB9Q8&t=407s) 比较好的把 Django 与 React 以及 D3 结合在一起为警局提供数据看板项目。 166 | 167 | 168 | 169 | ## 修改记录 170 | 171 | ### 2017-10-23 更新内容 172 | * Python 基础部分:不再推荐《Python学习手册(第4版)》。基础书籍数量保持三本,增加推荐新书籍,本书不再推荐。 173 | 174 | 被删除内容: 175 | 176 | >[《Python学习手册(第4版)》](https://www.amazon.cn/Python%E5%AD%A6%E4%B9%A0%E6%89%8B%E5%86%8C-%E9%B2%81%E7%89%B9%E5%85%B9/dp/B004TUJ7A6/ref=sr_1_1?ie=UTF8&qid=1498793035&sr=8-1&keywords=python+%E5%AD%A6%E4%B9%A0%E6%89%8B%E5%86%8C) ([Learning Python, 5th Edition](https://www.amazon.com/Learning-Python-5th-Mark-Lutz/dp/1449355730/ref=sr_1_1?ie=UTF8&qid=1498803998&sr=8-1&keywords=learning+python))本书中文是第四版,英文已经更新到第五版。该作者长期从事 Python 教育,他知道学习者通常会问什么问题,所以讲解也是比较详细。如果你需要快速入门 Python ,不推荐这本书。但是相信你在 Python 进阶过程中,迟早会遇到一些很 Pythonic 的问题,比如:字典的三种创建方式、列表推导式(list comprehension)和装饰器(decorator)。你可以在这里快速找到详细的讲解。作者的另外还有两本高质量的 Python 书值得一读:[Python Pocket Reference: Python In Your Pocket (Pocket Reference (O'Reilly))](https://www.amazon.com/Python-Pocket-Reference-Your-OReilly/dp/1449357016/ref=la_B000APH2C4_1_2?s=books&ie=UTF8&qid=1498794090&sr=1-2) 以及[Programming Python: Powerful Object-Oriented Programming](https://www.amazon.com/Programming-Python-Powerful-Object-Oriented/dp/0596158106/ref=la_B000APH2C4_1_3?s=books&ie=UTF8&qid=1498794090&sr=1-3)。 177 | 178 | * Python 基础部分:增加推荐《Python 基础教程》 179 | 180 | * Django 进阶部分,2. 书籍:增加《Python Web 测试驱动方法》。 181 | 182 | * Django 进阶部分,3. 博客:增加 "Huang Huang 的博客"。 183 | 184 | * Django RESTful API,2. 视频:增加 "Vue+Django REST framework 打造生鲜电商项目"。 185 | 186 | * 修改部分格式错误。 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /SVN模块/README.md: -------------------------------------------------------------------------------- 1 | ## SVN for Python 2 | 3 | **描述:** 4 | 5 | SVN的Python版本 6 | 7 | **环境:** 8 | 9 | 1. Python2.7 10 | 2. LinuxCentos * 11 | 3. Subversion-1.6.11-15.el6_7.x86_64 12 | 4. svn 0.3.44 for python 13 | 14 | **安装:** 15 | 16 | pip install svn 17 | 18 | 19 | **注意:** 20 | 21 | 1. 代码文件只是实例代码,详细请看官方文档 22 | 2. 代码有部分注释,单一调试请去掉注释即可 23 | 3. 建议在Linux上操作,不建议Windows。 24 | 25 | 26 | **参考文档:** 27 | 28 | svn模块官方:[https://pypi.python.org/pypi/svn](https://pypi.python.org/pypi/svn) -------------------------------------------------------------------------------- /SVN模块/SVN接口模块.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # Author:eycode 3 | # 使用SVN接口 4 | # 安装模块:pip install svn 5 | # 参考文档:https://pypi.python.org/pypi/svn 6 | # 建议操作系统:Linux、Unix 7 | 8 | # CheckoutSVN: 9 | import svn.remote 10 | r = svn.remote.RemoteClient("http://192.168.0.220:54162/svn/eycode/", username="eycode", password="eycode") 11 | r.checkout("/tmp") 12 | 13 | # 分析: 14 | # svn.remote.RemoteClient(url, username, password) 15 | # checkout(path) 16 | 17 | # 注意:直接生成SVN中的目录,即自动更新数据 18 | 19 | # 查看该目录: 20 | # [root@16bf6ea74dc8 sh]# ll /tmp/ 21 | # total 8 22 | # drwxr-xr-x 3 root root 4096 Jul 6 10:19 0302-1.5.0 23 | 24 | # 0302-1.5.0目录是SVNcheckout后自动更新生成的目录 25 | 26 | 27 | 28 | 29 | # 查看日志: 30 | import svn.local 31 | log = svn.local.LocalClient("/tmp/0302-1.5.0") 32 | for i in log.log_default(): 33 | print i 34 | 35 | # 返回结果: 36 | # LogEntry(date=datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), msg=None, revision=5, author='eycode', changelist=None) 37 | 38 | 39 | 40 | 41 | # 获取更新文件列表(文件名模式) 42 | import svn.local 43 | l = svn.local.LocalClient("/tmp/0302-1.5.0") 44 | for i in l.list(): 45 | print i 46 | 47 | 48 | # 返回结果: 49 | # GisApp-Ybo-release.apk 50 | # GisApp-vivo-release.apk 51 | # GisApp-xiaomi-release.apk 52 | 53 | # 值得注意的是: 54 | # 当某个客户端提交数据,本地客户端重新更新数据在同一个目录下时,会将之前的数据名同样显示出来 55 | 56 | 57 | 58 | # 获取更新文件列表(字典模式) 59 | import svn.local 60 | l = svn.local.LocalClient("/tmp/0302-1.5.0") 61 | for i in l.list(extended=True): 62 | print i 63 | 64 | # 返回结果: 65 | # {'kind': 'file', 'is_directory': False, 'name': 'GisApp-Ybo-release.apk', 'author': 'eycode', 'date': datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), 'timestamp': datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), 'commit_revision': 5, 'size': 56060566} 66 | # {'kind': 'file', 'is_directory': False, 'name': 'GisApp-vivo-release.apk', 'author': 'eycode', 'date': datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), 'timestamp': datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), 'commit_revision': 5, 'size': 55504787} 67 | # {'kind': 'file', 'is_directory': False, 'name': 'GisApp-xiaomi-release.apk', 'author': 'eycode', 'date': datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), 'timestamp': datetime.datetime(2017, 7, 4, 6, 26, 54, 671678, tzinfo=tzutc()), 'commit_revision': 5, 'size': 55504678} 68 | # {'kind': 'file', 'is_directory': False, 'name': 'test.txt', 'author': 'eycode', 'date': datetime.datetime(2017, 7, 6, 2, 47, 39, 273350, tzinfo=tzutc()), 'timestamp': datetime.datetime(2017, 7, 6, 2, 47, 39, 273350, tzinfo=tzutc()), 'commit_revision': 6, 'size': 0} -------------------------------------------------------------------------------- /SendMail/Django 发送邮件配置.md: -------------------------------------------------------------------------------- 1 | # Django 使用 QQ / 新浪邮箱发送邮件配置 2 | 3 | ### 环境: 4 | - python 2.7 or 3.5 5 | - django 1.9 or 1.10 6 | 7 | ## 先说 QQ 邮箱: 8 | 9 | **第一步,首先需要一个 QQ 邮箱授权码:** 10 | 进入QQ 邮箱点击设置 11 | 12 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1430985-002819268fa04553.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | ** 第二步,开启服务,并且生成授权码** 15 | 16 | 17 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1430985-306c32b9c08adc6e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 18 | 19 | ** 第三步, setting.py 配置** 20 | ```python 21 | EMAIL_HOST = 'smtp.qq.com' 22 | EMAIL_PORT = 25 23 | EMAIL_HOST_USER = 'xxx@qq.com' # 你的 QQ 账号 24 | EMAIL_HOST_PASSWORD = '刚刚复制的授权码(不是你的 QQ 密码!!!)' 25 | EMAIL_USE_TLS = True # 这里必须是 True,否则发送不成功 26 | EMAIL_FROM = 'xxx@qq.com' # 你的 QQ 账号 27 | ``` 28 | EMAIL_HOST_USER 和 EMAIL_USE_TLS 最好保持一致 29 | 30 | ** 第四步,发送邮箱的逻辑** 31 | ```python 32 | from django.core.mail import send_mail 33 | 34 | email_title = '邮件标题' 35 | email_body = '邮件内容' 36 | email = 'xxx@xxx.com' #对方的邮箱 37 | send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) 38 | 39 | if send_status: 40 | # 发送成功 41 | ``` 42 | 43 | 参考 [腾讯 QQ 邮箱](https://kf.qq.com/faq/120322fu63YV130422nqIrqu.html) 44 | 45 | --- 46 | 47 | 48 | ## 新浪邮箱就比较简单了 49 | 50 | ![新浪邮箱](http://upload-images.jianshu.io/upload_images/1430985-c08b44394f1bf3e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 51 | 开启服务 52 | 53 | ```python 54 | EMAIL_HOST = "smtp.sina.com" 55 | EMAIL_PORT = 25 56 | EMAIL_HOST_USER = "xxx@sina.com" # 你的邮箱账号 57 | EMAIL_HOST_PASSWORD = "xxxx" # 你的邮箱密码 58 | EMAIL_USE_TLS = False # 这里是 False 59 | EMAIL_FROM = "xxx@sina.com" # 你的邮箱账号 60 | ``` 61 | 62 | --- 63 | 以上两种方法亲测都能成功发送邮件,如果帮到了您,请点赞 :) 64 | 65 | 66 | 如果对您有帮助,请点击喜欢,谢谢~ 67 | -------------------------------------------------------------------------------- /SendMail/README.md: -------------------------------------------------------------------------------- 1 | ## 通过Python发邮件 2 | 3 | #### 描述: 4 | 5 | 在自动化监控中,经常用到通过Python脚本或Linux原带的Sendmail来发送监控邮件 6 | 7 | 1. Python脚本邮件:代码简单,功能强大,例如:发送图片,附件,以Html形式展开,报表等等。最为骄傲的是主要是安装python的系统都可以使用脚本 8 | 9 | 2. Linux自带的sendmail等邮件软件:功能强大,但一般新手或非专业管理员是玩不转的,配置文件复杂,一个简单的功能可能需要几个依赖才能玩转, 不兼容主流的邮箱服务器,配置SSL协议更加复杂,所以不建议使用。 10 | 11 | #### 应用场景 12 | 13 | 1. 常用于监控邮件发送(Zabbix,rrdtool等等) 14 | 2. 后台发送注册邮件(Django),不过Django已经集成了,更加方便使用。 15 | 16 | #### 环境: 17 | 18 | 1. Python 2.6 + (最低要求) 19 | 20 | 2. 任何系统 21 | 22 | 23 | #### 参考文档: 24 | 25 | 1. smtplib模块官方文档:[https://docs.python.org/2/library/email-examples.html](https://docs.python.org/2/library/email-examples.html) 26 | 27 | 2. 廖雪峰Python2.7 发送邮件: 28 | [http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832745198026a685614e7462fb57dbf733cc9f3ad000](http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832745198026a685614e7462fb57dbf733cc9f3ad000) -------------------------------------------------------------------------------- /SendMail/发送图片.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #coding:utf-8 3 | import smtplib 4 | from email.mime.multipart import MIMEMultipart 5 | from email.mime.text import MIMEText 6 | from email.mime.image import MIMEImage 7 | 8 | # 邮件服务器 9 | host = "smtp.163.com" 10 | 11 | # 邮件标题 12 | title = u"服务器日常流量监控" 13 | 14 | # 收件人 15 | send_to = "******@eycode.com" 16 | 17 | # 发件人 18 | send_from = "******@163.com" 19 | 20 | 21 | # 读取图片文件,值得注意是读取图片!! 22 | def addimg(src,imgid): 23 | fp = open(src,'rb') 24 | msgImage = MIMEImage(fp.read()) 25 | fp.close() 26 | msgImage.add_header('Content-ID',imgid) 27 | return msgImage 28 | 29 | msg = MIMEMultipart('related') 30 | 31 | 32 | # 邮件以html格式展示 33 | msgtext = MIMEText("""及图片 34 |
35 | 36 | 37 | 38 | 39 | 42 |
*官网性能数据 更多>>
40 | 41 |
""","html","utf-8") 43 | 44 | now = datetime.datetime.now() 45 | 46 | # 获取图片地址 47 | image_file = "%s-eth0.png" % now.strftime('%Y-%m-%d') 48 | 49 | # 文本 50 | msg.attach(msgtext) 51 | 52 | # 将图片文件 53 | msg.attach(addimg(image_file,"io")) 54 | 55 | msg['Subject'] = title 56 | msg['From']= send_from 57 | msg['To']= send_to 58 | 59 | try: 60 | server = smtplib.SMTP() 61 | 62 | # 协议端口 63 | server.connect(HOST,"25") 64 | server.starttls() 65 | 66 | # 登陆 67 | server.login("***@eycode.com","****密码*****") 68 | server.sendmail(FROM, TO, msg.as_string()) 69 | server.quit() 70 | print "邮件发送成功!" 71 | except Exception, e: 72 | print "失败:"+str(e) 73 | -------------------------------------------------------------------------------- /SendMail/通过SSL发送邮件.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | #!/usr/bin/env python 3 | 4 | import smtplib,datetime,sys 5 | from email.mime.multipart import MIMEMultipart 6 | from email.mime.text import MIMEText 7 | from email.mime.application import MIMEApplication 8 | 9 | username = sys.argv[1] 10 | passwd = sys.argv[2] 11 | 12 | _user = "oa@eycode.com" 13 | _pwd = "密码" 14 | _to_list = ["%s@eycode.com"%username] 15 | 16 | msg = MIMEMultipart() 17 | 18 | # 设置邮件编码 19 | msg["Accept-Language"] = "zh-CN" 20 | msg["Accept-Charset"] = "ISO-8859-1,utf-8" 21 | 22 | # 邮件标题 23 | msg["Subject"] = u"VPN信息,请注意保密" 24 | msg["From"] = _user 25 | msg['to'] = ','.join(_to_list) 26 | 27 | # 内容部分 28 | part = MIMEText(""" 29 | 你好 \n 30 | 你的VPN帐号已经开通正常 \n 31 | 帐号:%s \n 32 | 密码:%s \n 33 | 压缩包密码:imay \n 34 | 使用教程请看附件 \n 35 | """ % (username,passwd) ,_charset="utf-8") 36 | msg.attach(part) 37 | 38 | # 附件部分 39 | part = MIMEApplication(open("VPN.rar",'rb').read()) 40 | part.add_header('Content-Disposition', 'attachment', filename="VPN.rar") 41 | msg.attach(part) 42 | 43 | # 使用SSL协议进行发送邮件 44 | server = smtplib.SMTP_SSL() 45 | server.connect("smtp.exmail.qq.com", 465) 46 | server.login(_user, _pwd) 47 | server.sendmail(_user, _to_list, msg.as_string()) 48 | server.close() 49 | -------------------------------------------------------------------------------- /apache+django 后台样式错误.md: -------------------------------------------------------------------------------- 1 | 注意以下条件: 2 | 1. 在django项目中已经新创建了一个static目录,并在setting.py文件中指向了该目录 3 | 2. 运行环境使用apache+django,在apache配置文件中指定了static目录的路径为新项目下的路径!!!!! 4 | 5 | 符合以上两个条件后出现django后台CSS文件找不到情况! 6 | 7 | 解决方案: 8 | 1. 找到django的安装目录: 9 | ```bash 10 | Python 2.7.3 (default, Mar 10 2017, 02:35:03) 11 | [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2 12 | Type "help", "copyright", "credits" or "license" for more information. 13 | >>> import django 14 | >>> django.__file__ 15 | '/usr/local/python2.7/lib/python2.7/site-packages/Django-1.9.10-py2.7.egg/django/__init__.pyc' 16 | ``` 17 | 18 | 19 | 2. 进入Django安装目录中 20 | ```bash 21 | [root@9683705d680e static]# pwd 22 | /usr/local/python2.7/lib/python2.7/site-packages/Django-1.9.10-py2.7.egg/django/contrib/admin/static 23 | [root@9683705d680e static]# 24 | ``` 25 | 26 | 27 | 3. 复制文件到新的static目录中 28 | ``` 29 | [root@9683705d680e static]# cp -a admin /webstatus/webstatus/static/ 30 | [root@9683705d680e static]# ll /webstatus/webstatus/static/ 31 | total 16 32 | drwxr-xr-x 6 root root 4096 Mar 10 02:35 admin 33 | drwxr-xr-x 2 root root 4096 Mar 13 07:53 css 34 | drwxr-xr-x 2 root root 4096 Mar 13 04:11 images 35 | drwxr-xr-x 2 root root 4096 Mar 13 07:56 js 36 | [root@9683705d680e static]# 37 | ``` 38 | 39 | 4. 解决!!!!刷新下地址即可!!! 40 | 41 | 42 | -------------------------------------------------------------------------------- /django 返回 html 函数的区别.md: -------------------------------------------------------------------------------- 1 | ## django开发中,有不同的返回给前端的函数,下面介绍几个,在开发中遇到的小情况: 2 | ``` python 3 | return render(request, "vpn_add.html") #最常用的 4 | return HttpResponseRedirect(reverse('vpn_add')) #比较常用的(提交页面或跳转时常用) 5 | return render_to_response("vpn_add.html", {"meg": 1}) #一般用的 6 | ``` 7 | 8 | 9 | ### 第一种: `render(request, "页面地址", 返回值)` 10 | 常用场景:get页面的时候最常用 11 | 依赖模块:`from django.shortcuts import render` 12 | 13 | 例子:(部分代码) 14 | ```python 15 | class test(Views): 16 | def get(self, request): 17 | return render(request, "index.html", {"test": "返回值"}) 18 | ``` 19 | 20 | 分析:当用户访问一个页面时,首先使用get提交方式获取页面数据,加载数据,在这个方面上render()函数是一个很方便很使用的函数 21 | 22 | 注意:页面跳转的时候需要注意 23 | 直接使用rander()函数跳转:页面是跳转了,但是是一种伪跳转,页面已经显示了跳转的内容,但是留意URL地址后发现。 24 | 依然是使用着注册页面的URL地址,刷新页面后依然跳回到原地址问题(这个问题导致的原因是url.py文件指定的URL函数导致) 25 | 26 | 27 | ### 第二种:`HttpResponseRedirect(reverse('地址名'))` 28 | 常用场景:在提交表单时使用情况很多 29 | 依赖模块: 30 | ```python 31 | from django.shortcuts import HttpResponseRedirect 32 | from django.core.urlresolvers import reverse 33 | ``` 34 | 35 | 例子:(部分代码) 36 | ```python 37 | def post(self, request): 38 | loginform = UserLoginForm(request.POST) 39 | if loginform.is_valid(): 40 | user = request.POST.get("username", "") 41 | passwd = request.POST.get("password", "") 42 | auth = authenticate(username = user, password = passwd) 43 | if auth is not None: 44 | if auth.is_active: 45 | login(request, auth) 46 | return HttpResponseRedirect(reverse('video')) 47 | ``` 48 | 49 | 分析:这个场景很重要,当一个用户提交信息后,正常来说提交成功后会自动刷新页面然后等待下一次提交状态,在三种返回机制中 50 | 第一种和第三种机制是没有办法实现,都会出现一个情况“在页面刷新后,无端端重新提交一次”,导致重新刷新一次数据库,这样用户体验和对服务器压力不好,但是奇怪的是,这种情况不是经常出现,会偶然出现一次。 51 | 52 | 注意: 53 | 1. 这个函数是没有办法传递参数到前端页面的,也就是说,这个完完整整是路径重定向作用。 54 | 2. 使用 `HttpResponseRedirect()`函数跳转,这是真实的跳转方式,从一个地址只向另一个地址,从一个页面指向另一个页面。 55 | 对比:如果是原页面跳转使用`rander()`,如果交互完成后跳转到指定URL使用`HttpResponseRedirect()` 56 | 57 | 58 | ### 第三种:`render_to_response`(“跳转页面”, 参数) 59 | 常用场景:post和get刷新时都可以,比render()函数高级,灵活使用 60 | 依赖模块: 61 | ``` 62 | from django.shortcuts import render_to_response 63 | ``` 64 | 例子:无 65 | -------------------------------------------------------------------------------- /django使用redis+celery异步执行任务.md: -------------------------------------------------------------------------------- 1 | # django使用redis+celery异步执行任务 2 | 3 | 参考地址: 4 | http://docs.jinkan.org/docs/celery/index.html 官方网站文档 5 | http://www.cnblogs.com/aguncn/p/4947092.html 大神作品 6 | http://python.jobbole.com/81953/ 大神作品 7 | http://www.mamicode.com/info-detail-986285.html 大神作品 8 | 9 | 10 | 安装以下扩展包: 11 | ```bash 12 | pip install celery 13 | pip install celery-with-redis 14 | pip install django-celery 15 | ``` 16 | 17 | 安装Redis服务 (不说了,自己百度) 18 | 19 | ### steup1:在seting.py文件中设置关联 20 | ```python 21 | import djcelery # 导入模块 22 | 23 | 24 | djcelery.setup_loader() 25 | CELERY_TIMEZONE='Asia/Shanghai' //设置启动celery服务的时间 26 | TIME_ZONE= 'Asia/Shanghai' //设置本地时间,celery时间要与本地时间一致 27 | BROKER_URL = 'redis://localhost:6379/0' 28 | CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' //Redis 中存储任务的状态和返回值(如果使用redis缓存层,就注释掉) 29 | CELERY_ACCEPT_CONTENT = ['json'] 30 | CELERY_TASK_SERIALIZER = 'json' 31 | CELERY_RESULT_SERIALIZER = 'json' 32 | ``` 33 | 34 | 35 | ### steup2:在seting.py文件同目录下创建celery.py文件 36 | ```python 37 | from __future__ import absolute_import # 这句代码一定是文件的第一行,一定要在第一句,否则报错 38 | 39 | import os 40 | from celery import Celery 41 | from django.conf import settings 42 | 43 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名.settings') #项目名 44 | 45 | app = Celery('celerytest') # 定义项目名(django的项目名) 46 | 47 | app.config_from_object('django.conf:settings') 48 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 49 | 50 | @app.task(bind=True) # 这段代码是打印信息 51 | def debug_task(self): 52 | print('Request: {0!r}'.format(self.request)) 53 | ``` 54 | 55 | 56 | ### Steup3:在celery.py文件同目录下的__init__.py中写以下代码: 57 | ```python 58 | from __future__ import absolute_import 59 | from .celery import app as celery_app # 重命名模块名将app重名为celery_app 60 | ``` 61 | 62 | 63 | ### Step4:在需要添加任务的app目录下创建tasks.py文件,这个文件负责处理相关的函数 64 | ```javascript 65 | # coding:utf-8 66 | 67 | from operation import celery_app #导入模块 68 | # from celery import shared_task 69 | from django.core.mail import EmailMessage 70 | from operation.settings import EMAIL_FROM 71 | 72 | @celery_app.task # 使用装饰器,注入app中使用 73 | ``` 74 | 75 | 76 | # 以下就是任务的代码,很简单,就是发送邮件。 77 | ```python 78 | def SendMailFile(email, user, password): 79 | email_title = "VPN信息,请注意保密" 80 | email_body = "你好 \n 你的VPN帐号已经开通正常 \n帐号:{0} \n密码:{1} \n压缩包密码:imay \n使用教程请看附件".format(user, password) 81 | message = EmailMessage(email_title, email_body, EMAIL_FROM, [email]) 82 | 83 | keyfile = open("/sh/KeyFile.rar", 'r') 84 | message.attach("KeyFile.rar", keyfile.read(), 'application/x-rar-compressed') 85 | status = message.send() 86 | return status 87 | ``` 88 | 89 | 90 | ### Step5:在views.py文件中调用异步函数(部分代码) 91 | ```python 92 | from vpnmanage.tasks import SendMailFile # 导入tasks文件中的函数 93 | # 发送邮件(测试异步发送邮件) 94 | sendmail_status = SendMailFile.delay(email, user, password) # 注意:函数需要的参数由delay()提供 95 | ``` 96 | 97 | 98 | ### Step6:启动异步任务 99 | ```python 100 | celery -A operation worker -l info # operation是项目,在celery文件定义的 101 | ``` 102 | 103 | 注意:如果提示celery命令没有,你就去软连接一下即可 104 | `ln -fs /usr/local/python2.7/bin/celery /usr/bin/ 即可` 105 | 106 | 107 | 108 | 注意:添加一个任务就要重启一次异步任务 109 | 以下例子是同一个app下的多个任务: 110 | 111 | tasks.py文件: 112 | ```python 113 | # coding:utf-8 114 | 115 | from operation import celery_app 116 | # from celery import shared_task 117 | from django.core.mail import EmailMessage 118 | from operation.settings import EMAIL_FROM 119 | 120 | import paramiko 121 | 122 | @celery_app.task 123 | def SendMailFile(email, user, password): 124 | email_title = "VPN信息,请注意保密" 125 | email_body = "你好 \n 你的VPN帐号已经开通正常 \n帐号:{0} \n密码:{1} \n压缩包密码:imay \n使用教程请看附件".format(user, password) 126 | message = EmailMessage(email_title, email_body, EMAIL_FROM, [email]) 127 | 128 | keyfile = open("/sh/KeyFile.rar", 'r') 129 | message.attach("KeyFile.rar", keyfile.read(), 'application/x-rar-compressed') 130 | status = message.send() 131 | return status 132 | 133 | @celery_app.task() 134 | def SshClient(user, password): 135 | username = "root" 136 | passwd = "imay2016" 137 | host = "192.168.0.220" 138 | port = 22 139 | remotefile = "/vpn/psw-file" 140 | 141 | ssh = paramiko.SSHClient() 142 | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 143 | 144 | ssh.connect(host, port, username, passwd) 145 | ssh.exec_command("echo {0} {1} >> {2}".format(user, password, remotefile)) 146 | ssh.close() 147 | ``` 148 | 149 | 150 | views.py文件: 151 | ```python 152 | from vpnmanage.tasks import SendMailFile, SshClient 153 | # 发送邮件(测试异步发送邮件) 154 | sendmail_status = SendMailFile.delay(email, user, password) 155 | 156 | 157 | # 写入VPN文件(测试异步写入文件) 158 | SshClient.delay(user, password) 159 | ``` 160 | 161 | 162 | 163 | 启动脚本: 164 | ```python 165 | #!/bin/bash 166 | # Author:eycode 167 | # Date:2017-5-17 168 | # 该脚本是celeryd服务启动 169 | # celeryd服务为异步服务 170 | # 需要 171 | # django项目路径 172 | # celery文件路径 173 | # celery项目名 174 | 175 | django_poject_path="/webstatus/webstatus" 176 | celery_path="/usr/local/python2.7/bin/celery" 177 | django_poject="webstatus" 178 | 179 | 180 | if [ ! -f $celery_path ] 181 | then 182 | echo "celery command not found" 183 | exit 1 184 | fi 185 | 186 | 187 | start(){ 188 | cd $django_poject_path 189 | $celery_path -A $django_poject worker -l info &> /dev/null & 190 | sleep 2 191 | ps xau |grep celery | grep -v "grep" &> /dev/null 192 | if [ $(echo $?) -eq 0 ] 193 | then 194 | echo "start celeryd server success !" 195 | else 196 | echo "start celeryd server faild !" 197 | fi 198 | } 199 | 200 | 201 | 202 | stop(){ 203 | pid_list=$(ps xau |grep celery |grep -v "grep" |awk '{print $2}') 204 | for i in $pid_list 205 | do 206 | kill $i &> /dev/null 207 | done 208 | } 209 | 210 | case $1 in 211 | start) 212 | start ;; 213 | restart) 214 | stop 215 | start ;; 216 | stop) 217 | stop ;; 218 | *) 219 | echo "Used: service celeryd {start | restart | stop}" 220 | esac 221 | ``` 222 | 223 | -------------------------------------------------------------------------------- /django使用定时更新任务.md: -------------------------------------------------------------------------------- 1 | # django使用定时更新任务 2 | 3 | ### step1:安装django-crontab模块 4 | `pip install django-crontab` 5 | 注意:django的任务计划有两个模块,一个是django-crontab,另一个是django-cron 6 | 我们使用django-crontab模块,这个配置起来非常简单 7 | 8 | 9 | ### step2:在setting.py中添加为APP 10 | ```python 11 | INSTALLED_APPS = [ 12 | # ... 13 | "django_crontab", #注意:加载的模块名一定要注意 14 | ] 15 | ``` 16 | 17 | 18 | ### step3:自定义命令函数:(重点) 19 | 在app项目下创建management目录,再在该目录下创建commands目录,在commands目录创建py文件,该文件为自定义命令 20 | 例如: 21 | app目录名/management/commands/mysql_count.py 22 | 23 | ```python 24 | # coding:utf-8 25 | # 自定义django-admin命令 26 | # python manage.py mysql_count 27 | # 注意:在更新的时候为什么不能用get,只能用filter? 28 | # get获取的数据是一个字段,而filter获取的是一个列表,在更新中,应该是针对列表中的字段进行更新 29 | # 所以只能用filter 30 | 31 | __author__ = 'eycode' 32 | __date__ = '2017/4/11/011 11:33' 33 | 34 | from django.core.management.base import BaseCommand 35 | from vpnmanage.models import VpnManage, VpnLogs 36 | 37 | 38 | class Command(BaseCommand): #继承BaseCommand类 39 | def handle(self, *args, **options): # 一定是handle函数 40 | vpnlist = VpnManage.objects.all() 41 | vpnlist = [ str(i).split(" ", 3)[1] for i in vpnlist ] 42 | 43 | for user in vpnlist: 44 | chk_log = VpnLogs.objects.filter(user = user) 45 | if len(chk_log) != 0: 46 | # 统计登录成功次数 47 | success = VpnLogs.objects.filter(user=user, status = "Successful") 48 | user_success = success.count() 49 | 50 | # 统计登录失败次数 51 | user_fail_list = VpnLogs.objects.filter(user=user, status="Incorrect") 52 | user_fail = user_fail_list.count() 53 | 54 | # # 统计登录总次数 55 | user_counnt = int(user_success) + int(user_fail) 56 | 57 | # 统计最近登录时间 58 | user_latetime = VpnLogs.objects.filter(user = user, status = "Successful").order_by('-time')[0] 59 | user_latetime = str(user_latetime) 60 | 61 | VpnManage.objects.filter(user=user).update(scount=user_success, fcount=user_fail, logincount=user_counnt, latetime=user_latetime) 62 | # print "%s 更新" %user 63 | else: 64 | VpnManage.objects.filter(user=user).update(scount="0", fcount="0", logincount="0", latetime="no login") 65 | 66 | ``` 67 | 68 | 69 | ### step4:测试命令的执行是否正常 70 | python manage.py mysql_count 71 | 注意:mysql_count为文件名。 72 | 73 | 74 | 75 | ### step5:添加计划任务: 76 | 在setting.py文件中: 77 | ```python 78 | CRONJOBS = [ 79 | ('*/5 * * * *', 'django.core.management.call_command', ['mysql_count']), 80 | ] 81 | ``` 82 | 83 | 解析: 84 | */5 * * * * :每5分钟执行一次 85 | django.core.management.call_command:相当于python manage.py 86 | mysql_count:自定义命令函数 87 | 88 | 89 | 90 | ### step6:执行任务计划 91 | ```bash 92 | [root@9683705d680e operation]# python manage.py crontab add 93 | no crontab for root 94 | adding cronjob: (1eb1cfc7b7f566494684323c57922190) -> ('*/5 * * * *', 'django.core.management.call_command', ['mysql_count']) 95 | [root@9683705d680e operation]# 96 | [root@9683705d680e operation]# crontab -l 97 | */5 * * * * /usr/bin/python /Operationsmanage/operation/manage.py crontab run 1eb1cfc7b7f566494684323c57922190 # django-cronjobs for operation 98 | [root@9683705d680e operation]# 99 | ``` 100 | 101 | 102 | 注意:需要服务器上有安装crond服务才能使用 103 | ```bash 104 | yum -y install vixie-cron 105 | yum -y install crontabs 106 | ``` 107 | --------------------------------------------------------------------------------