Django框架基础一
1、web框架本质
所有的Web应用本质就是一个socket服务端,用户使用的浏览器就是socket客户端
软件开发架构:C/S架构和B/S架构,B/S架构本质也是C/S
1、纯手撸简易版web框架,实现根据用户输入的后缀不同内容返回不同的结果
1 import socket 2 3 server = socket.socket() 4 server.bind(('127.0.0.1', 9876)) 5 server.listen(5) 6 7 8 while True: 9 conn, addr = server.accept() 10 data = conn.recv(1024) 11 # Http协议的响应信息,HTTP/1.1表示当前协议为Http。1.1是协议的版本。200表示成功, OK表示好的 12 conn.send(b'HTTP/1.1 200 OK\r\n\r\n') 13 # print(data) 14 data = data.decode('utf8') # 返回的是一串字符串,第二个字符串就是用户输入的后缀 15 # 获取用户输入的后缀内容 16 target_url = data.split('\r\n')[0].split(' ')[1] 17 # 判断用户输入的内容返回不同的内容 18 if target_url == 'index': 19 conn.send(b'index') 20 elif target_url == 'login': 21 conn.send(b'login') 22 else: 23 conn.send(b'404 error') 24 conn.close()
由于socket代码是我们自己写的,HTTP数据也是我们自己处理的太过麻烦,所以有了wsgiref模块
2、wsgiref模块
wsgiref模块可以帮我们封装我们写的web框架中的socket server部分
根据功能不同拆分成不同的文件:
urls.py:路由与视图函数的对应关系
views.py:里面就是存放一堆视图函数(视图函数可以是函数也可以是类)
templates文件夹(模板文件夹):里面放一堆HTML文件
用户在浏览器窗口输入url之所以能获取相应的资源是因为后端早已经开设相应的资源接口
1 from wsgiref.simple_server import make_server 2 from urls import urls 3 from views import * 4 5 6 def run(env, response): 7 ''' 8 :param env: 请求相关的所有数据,接收的是大字典,里面的PATH_INFO参数就是用户输入的url后缀 9 :param response: 响应相关的所有数据 10 :return: 返回浏览器接收的内容 11 ''' 12 response('200 OK', []) 13 target_url = env.get('PATH_INFO') 14 # 此处应该根据用户输入进行逻辑判断,为减少代码用for循环实现 15 # 先定义一个变量存储可能匹配的函数名 16 func = None 17 for url in urls: 18 # 判断用户输入的是否与urls一致 19 if target_url == url[0]: 20 func = url[1] 21 # 一旦有响应就立刻结束,调转到响应url 22 break 23 # 判断是否有匹配上的 24 if func: 25 # 加括号调用 26 res = func(env) 27 else: 28 res = error(env) 29 return [res.encode('utf-8')] 30 31 32 if __name__ == '__main__': 33 # 监听'127.0.0.1:9876'一旦有访问就调用run执行 34 server = make_server('127.0.0.1', 9876, run) 35 # 启动服务端 36 server.serve_forever()
基于wsgiref模块已经文件拆分的特点,在后端开设相应的资源接口1. 先在urls文件中写url与函数对应的关系。2. 再去views文件中写对应的函数
1 from views import * 2 urls = [ 3 ('/index', index), 4 ('/login', login), 5 ('/get_time', get_time), 6 ]
def index(env): return 'index' def login(env): return 'login' def error(env): return '404 error'
1 # 需要返回一个HTML页面能实时获取时间的 2 import time 3 def get_time(env): 4 current_time = time.strftime('%Y-%m-%d %X') 5 with open(r'E:\Python\templates\get_time.html','r',encoding='utf-8') as f: 6 data = f.read() 7 # 将HTML中的文本xxx替换成当前时间 8 data = data.replace('xxx',current_time) 9 return data
动静态网页:静态网页:数据是写死的,不变的
动态网页:数据是动态获取的,比如获取当前时间,从数据库中获取数据
3、jinja2模块
提供了一个可以在HTML页面上书写类似于python后端的代码,来操作数据(模板语法)
下载:pip3 install jinja2
flask框架模板语法使用的就是jinja2模块,所有下载了flask框架就自动下载了jinja2模块
jinja2模板语法非常贴近python语法,但是并不是所有的框架使用的都是jinja2模板语法
模板语法:在HTML中使用类似于python语法,本质在后端实现的,前端根本不识别
1 from jinja2 import Template 2 def get_info(env): 3 user_dic = {'username': 'shen', 'password': 123, 'hobby': ['study','read']} 4 with open(r'E:\Python\templates\get_info.html','r', encoding='utf8') as f: 5 data = f.read() 6 temp = Template(data) 7 res = temp.render(xxx=user_dic) 8 return res
1 {{xxx}} 2 <p>{{xxx.username}}</p> 3 <p>{{xxx['password']}}</p> 4 <p>{{xxx.get('hobby')}}</p> 5 <p>{{xxx.get('hobby')[0]}}</p> 6 <p>{{xxx.get('hobby').1}}</p> 7 8 {%for user_dict in xxx %} 9 <tr> 10 <td>{{ user_dict.password }}</td> 11 <td>{{ user_dict.username }}</td> 12 <td>{{ user_dict.hobby }}</td> 13 </tr> 14 {% endfor %}
4、获取数据库中的数据展示到前端页面
1、路由与视图函数对应关系
2、视图函数
3、模板文件夹
4、模板语法(是在后端实现的,前端根本不识别)
{{}} :和变量有关
{% %}:和逻辑有关,for循环等
import pymysql def get_user(env): conn = pymysql.connect( host='127.0.0.1', port=3306, database='dome', charset='utf8', user='root', password='2694', autocommit=True ) cursor = conn.cursor(pymysql.cursors.DictCursor) sql = 'select * from user_info' cursor.execute(sql) data = cursor.fetchall() with open(r'E:\Python\templates\get_user.html','r',encoding='utf-8') as f: res = f.read() tmp = Template(res) res = tmp.render(xxx=data) return res
<body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table table-hover table-bordered"> <thead> <tr> <th>id</th> <th>username</th> <th>password</th> <th>hobby</th> </tr> </thead> <tbody> {%for user_dic in xxx %} <tr> <td>{{ user_dic.id }}</td> <td>{{ user_dic.username }}</td> <td>{{ user_dic.password }}</td> <td>{{ user_dic.hobby }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body>
2、python三大主流web框架
1、Django
优点:大而全,自身携带的组件和功能特别多
缺点:笨重,当功能不多时不需要使用很多其他的功能
2、flask
优点:小而精,自身携带的组件和功能特别少,但是第三方支持该框架的模块特别特别多,叠加起来甚至可以超过Django
缺点:受限于第三方模块
3、tornado
异步非阻塞,天然支持高并发,甚至可以开发游戏服务器
这三种框架基本都遵循下面三个步骤
A:socket
B:路由分发
C:模板渲染
django
A:用的别人的 wsgiref
B:自己写的
C:自己写的
flask
A:用的被人的 werkzeug
B:自己写的
C:用的别人的 jinja2
tornado
A,B,C都是自己的
3、Django框架
1、注意事项
-
计算机名称不能有中文
-
项目文件名也不能有中文
-
一个pycharm窗口就是单独的完整的项目
- python解释器的版本最好是3.6的,3.7版本会报错,下面有解决方法演示
2、版本
1.xx版本与2.xx版本
推荐使用1.11.09~1.11.13
如果已经安装不需要手动卸载,重新安装会自动先卸载之前的版本再安装
下载版本图如下:
-
第一种方式
通过从cmd输入命令行pip install django == 1.11.11
-
第二种方式
在pycharm的settings中找到project interpreter选项,在里面添加django1.11.11版本就行
4、测试是否安装成功
命令行输入django-admin
5、创建Django项目
创建django项目有两种方式,一种是通过命令行的形式,一种是通过pycharm的方式,下面先介绍命令行形式创建
-
-
mysite文件夹下的内容文件
-
-mysite
-
--init.py
-
--settings.py #项目配置文件,包括数据库的使用和静态文件的配置
-
--urls.py #路由与视图函数对应的关系(项目的总路由)
-
--wsgi.py
-
-manage.py # django的入口文件
-
注意:通过命令行创建时如果不在C盘创建,例如在D盘创建,可以通过D:回车来改变根目录,这样创建的项目就在D盘中了
启动django项目
python manage.py runserver # django默认的端口号是8000
注意:版本不兼容可能会出现一下错误
修改方法
-
尝试访问一次
将ip地址和断口号填写到浏览器就能够第一次访问django框架展示的欢迎页面
-
开始创建具有独立功能的app
创建app的命令行
python manage.py startapp app01
app01
-
--migrations 文件夹 数据库改动记录(日志)
-
----init.py
-
--init.py
-
--admin.py django后台管理
-
--apps.py 注册app相关
-
--models.py 模型类(ORM)
-
--tests.py 测试文件(写一些测试代码)
-
--views.py 视图函数(**)
通过在8000端口后面加上/admin回车可以访问admin界面
解释:什么叫app
app指的是application(应用),不是我们手机上所使用的那种app,django其实是一个专注于开发app的web框架,一个空的django项目就类似于是一所大学,app就类似于大学里面的各个学院,每个app其实就类似于不同的功能模块 例如一个购物网站,里面有不同的比如用户模块,订单相关的模块,投诉相关的模块,每个功能模块就有一个与之相关的app,不同的模块推荐使用不同的app去开发,并且django支持多app
注意:1.app命名应该做到见名知意(若实在是一时想不起名字可以用数字代替一下)
2.刚才启动的时候文件夹会多一个db.sqlite3的小数据库
第一步:打开pycharm,进行创建
不要选择虚拟环境
在刚才修改文件路径名之后成功创建项目
第二步:启动项目
补充:若开启多个项目发现端口不够用或者无法找到那个快捷启动按钮,可以通过下面这个方法来解决
修改端口号
添加快捷启动服务
简化命令行命令
例如可以简化命令行创建app
第三步:修改配置
注册app(创建app后一定要去注册,)
中间件
templates配置问题
手动添加环境变量
数据库的绑定
注意:**命令行创建模式和pycharm创建模式的对比
"""
1.使用命令行创建的django项目是不会自动创建templates摸版本文件夹 你只能自己手动创建
2.命令行创建的django项目不但没有templates文件夹配置文件中也没有填写路径,需要自己手动添加os.path.join(BASE_DIR, 'templates')
而pycharm创建的会自动添加templates文件夹配置文件和路径以及app注册
"""
容易犯的错误
1.代码修改了始终没有效果
1.在同一个端口起了多个服务 一直跑的是最开始的那个服务
2.浏览器缓存问题
8、小白必会三板斧
1.HttpResponse
2.render
3.redirect