Django框架简介
1、web框架本质
所有的Web应用本质就是一个socket服务端,用户使用的浏览器就是socket客户端
软件开发架构:C/S架构和B/S架构,B/S架构本质也是C/S
1、纯手撸简易版web框架,实现根据用户输入的后缀不同内容返回不同的结果
import socket server = socket.socket() server.bind(('127.0.0.1', 9876)) server.listen(5) while True: conn, addr = server.accept() data = conn.recv(1024) # Http协议的响应信息,HTTP/1.1表示当前协议为Http。1.1是协议的版本。200表示成功, OK表示好的 conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # print(data) data = data.decode('utf8') # 返回的是一串字符串,第二个字符串就是用户输入的后缀 # 获取用户输入的后缀内容 target_url = data.split('\r\n')[0].split(' ')[1] # 判断用户输入的内容返回不同的内容 if target_url == 'index': conn.send(b'index') elif target_url == 'login': conn.send(b'login') else: conn.send(b'404 error') conn.close()
由于socket代码是我们自己写的,HTTP数据也是我们自己处理的太过麻烦,所以有了wsgiref模块
2、wsgiref模块
wsgiref模块可以帮我们封装我们写的web框架中的socket server部分
把路由关系与函数对应关系全写在一个py文件太过冗余,所以根据功能不同拆分成不同的文件:
urls.py:路由与视图函数的对应关系
views.py:里面就是存放一堆视图函数(视图函数可以是函数也可以是类)
templates文件夹(模板文件夹):里面放一堆HTML文件
用户在浏览器窗口输入url之所以能获取相应的资源是因为后端早已经开设相应的资源接口
from wsgiref.simple_server import make_server from urls import urls from views import * def run(env, response): ''' :param env: 请求相关的所有数据,接收的是大字典,里面的PATH_INFO参数就是用户输入的url后缀 :param response: 响应相关的所有数据 :return: 返回浏览器接收的内容 ''' response('200 OK', []) target_url = env.get('PATH_INFO') # 此处应该根据用户输入进行逻辑判断,为减少代码用for循环实现 # 先定义一个变量存储可能匹配的函数名 func = None for url in urls: # 判断用户输入的是否与urls一致 if target_url == url[0]: func = url[1] # 一旦有响应就立刻结束,调转到响应url break # 判断是否有匹配上的 if func: # 加括号调用 res = func(env) else: res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': # 监听'127.0.0.1:9876'一旦有访问就调用run执行 server = make_server('127.0.0.1', 9876, run) # 启动服务端 server.serve_forever()
基于wsgiref模块已经文件拆分的特点,在后端开设相应的资源接口1. 先在urls文件中写url与函数对应的关系。2. 再去views文件中写对应的函数
from views import * urls = [ ('/index', index), ('/login', login), ('/get_time', get_time), ]
def index(env): return 'index' def login(env): return 'login' def error(env): return '404 error'
# 需要返回一个HTML页面能实时获取时间的 import time def get_time(env): current_time = time.strftime('%Y-%m-%d %X') with open(r'E:\Python\templates\get_time.html','r',encoding='utf-8') as f: data = f.read() # 将HTML中的文本xxx替换成当前时间 data = data.replace('xxx',current_time) return data
动静态网页:静态网页:数据是写死的,不变的
动态网页:数据是动态获取的,比如获取当前时间,从数据库中获取数据
3、jinja2模块
提供了一个可以在HTML页面上书写类似于python后端的代码,来操作数据(模板语法)
下载:pip3 install jinja2
flask框架模板语法使用的就是jinja2模块,所有下载了flask框架就自动下载了jinja2模块
jinja2模板语法非常贴近python语法,但是并不是所有的框架使用的都是jinja2模板语法
模板语法:在HTML中使用类似于python语法,本质在后端实现的,前端根本不识别
from jinja2 import Template def get_info(env): user_dic = {'username': 'shen', 'password': 123, 'hobby': ['study','read']} with open(r'E:\Python\templates\get_info.html','r', encoding='utf8') as f: data = f.read() temp = Template(data) res = temp.render(xxx=user_dic) return res
/-{{}}双大括号表示变量相关-/
{{xxx}} <p>{{xxx.username}}</p> <p>{{xxx['password']}}</p> <p>{{xxx.get('hobby')}}</p> <p>{{xxx.get('hobby')[0]}}</p> <p>{{xxx.get('hobby').1}}</p>
/-{% %} 大括号内有%%表示逻辑相关-/ {%for user_dict in xxx %} <tr> <td>{{ user_dict.password }}</td> <td>{{ user_dict.username }}</td> <td>{{ user_dict.hobby }}</td> </tr> {% endfor %}
4、获取数据库中的数据展示到前端页面
1、路由与视图函数对应关系
2、视图函数
3、模板文件夹
4、模板语法(是在后端实现的,前端根本不识别)
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
优点:大而全,自身携带的组件和功能特别多
缺点:笨重,当功能不多时不需要使用很多其他的功能
socket部分用wsgiref,路由分发用自己写的,模板渲染自己写的
2、flask
优点:小而精,自身携带的组件和功能特别少,但是第三方支持该框架的模块特别特别多,叠加起来甚至可以超过Django
缺点:受限于第三方模块
socket部分用werkzeug,路由分发自己写的,模板渲染用jinja2
3、tornado
异步非阻塞,天然支持高并发,甚至可以开发游戏服务器
socket,路由分发,模板渲染都自己写
3、Django框架
1、注意事项
-
计算机名称不能有中文
-
项目文件名也不能有中文
-
一个pycharm窗口就是单独的完整的项目
- python解释器最好不要用3.7版本,会出现报错,在报错地方加个括号可解决
2、版本
1.xx版本与2.xx版本
推荐使用1.11.09~1.11.13
如果已经安装不需要手动卸载,重新安装会自动先卸载之前的版本再安装
3、安装
pip3 install django==1.11.11
4、测试是否安装成功
命令行输入django-admin
注意:python3.7与1.11.11不兼容可以更改Django的配置文件中一个数据即可
5、创建Django项目
1、命令行
1、创建Django项目 : django-admin startproject 项目名
例:创建一个mysite项目:django-admin startproject mysite
效果:会创建一个mysite的文件夹
2、启动Django项目(先切换到项目目录下)
python manage.py runserver host:port # host:port 可以不写 默认是本机的127.0.0.1:8000
3、创建具有独立功能的app , 通常app名要见名知意:python manage.py startapp app名
例:python manage.py startapp app01
app的概念:application应用
Django其实是一个专注于开发的app的web框架,一个空的Django框架就类似一所大学,一个个的app就相当于一个个学院,每个app就类似于不同的功能模块,不同的功能模块推荐使用不同的app去开发,Django支持多app
注意:1、使用命令行创建的Django项目不会创建templates模板文件夹,只能手动创建
2、命令行创建的Django项目配置文件settings中没有填写路径需要手动添加到环境变量中,pycharm创建的就会自动添加
2、pycharm快捷创建
pycharm启动Django
pycharm快捷创建app,会自动在配置文件中注册
6、Django主要文件功能
mysite/ ├── manage.py # 管理文件 ├── db.sqlite3 # django自带的一个小型用于本地测试的数据库(对日期格式的数据不是很敏感) └── mysite # 项目目录 ├── __init__.py ├── settings.py # 配置 ├── urls.py # 路由 --> URL和函数的对应关系 └── wsgi.py # runserver命令就使用wsgiref模块做简单的web server └── app01 # 创建的app ├──migrations文件夹 数据库改动记录 ——__init__.py ├── __init__.py ├── admin.py # Django后台管理 ├── apps.py # 注册app相关 ├── models.py # 模型类(ORM) ├── tests.py # 测试文件 └── views.py # 视图函数
7、容易犯错的点
(*********)注意创建app后一定要先去settings文件中注册
修改代码始终没有效果
1、在同一个端口起了多个服务一直运行的是最开始的那个服务
2、浏览器缓存问题
8、小白必会三板斧
1、HttpResponse:返回字符串
def index(request):
# return HttpResponse('字符串') return HttpResponse('你好 美女')
2、render:模板渲染(将数据在后端按照模板语法放入HTML对应的位置)
返回html页面,并且可以给HTML页面传数据
def login(request):
# return render(request, 'templates文件夹下的html文件',{传给HTML页面的数据}) return render(request,'login.html',{'user_dict':{'username':'shen','password':123},'xxx':'hello world'})
3、redirect:重定向
可以重定向到自己写的url上可以简写url只写结尾
也可以重定向到指定的url
def home(request): # return redirect('https://www.mzitu.com') return redirect('/index')
9、Django国际化配置
Django页面可以改成中文的,在配置文件中更改成下面的就行
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False