1121 Django基本
Django前戏
先纯手撸web代码,然后使用模块
一、课程导读
1、web应用
运行在浏览器上的应用
2、c/s b/s 架构
-
client/server:客户端服务器架构,C++
-
brower/server:浏览器服务器架构,Java、Python
-
底层均是基于socket
3、Python Web框架
a.socket b.页面路由 c.模板渲染
-
Django a用的wsgiref b自己写的 c自己写的 功能全面
-
Flask a用的第三方 b自己写的 c自己写的 小而轻
-
Tornado a自己写的 b自己写的 c自己写的 支持高并发
二、原生socket服务
- 目录结构
part1
-- index.html
-- server.py
- 基础socket服务
import socket
# 利用socket建立服务器对象
server = socket.socket()
# 设置ip和端口
server.bind(('127.0.0.1', 8001))
# 设置监听
server.listen(5)
print('服务器设置成功')
print('浏览器访问:http://127.0.0.1:8001')
while True:
# 阻塞等待客户端数据
client, address = server.accept()
# 接收数据
data = client.recv(1024)
print('接收到数据: ', data)
# 返回数据
client.send(b'Normal Socket Web')
# 关闭连接(必须关闭每一次连接)
client.close()
# 浏览器错误:发送的响应无效,原因:响应不满足http协议
'''
# 请求发来的数据
b'GET / HTTP/1.1\r\n
Host: 127.0.0.1:8001\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
Cookie: csrftoken=szfYLDVuqvRhlveNpNE2rp1GYOcI5x7mRNfvkRWTMRNRwWxXMZWOhL1MqknYJ7jg; sessionid=3pphvmw2icub0bea7nn02u6wev17k4uw\r\n
\r\n'
'''
三、http协议
什么是http协议
HTTP(HyperText Transport Protocol)是超文本传输协议
四大特性
- 基于TCP/IP协议基础上的应用层协议,底层实现仍为socket
- 基于请求-响应模式:通信一定是从客户端开始,服务器端接收到客户端一定会做出对应响应
- 无状态:协议不对任何一次通信状态和任何数据做保存
- 无连接:一次连接只完成一次请求-响应,请求-响应完毕后会立即断开连接
http工作原理(事务)
一次http操作称之为一个事务,工作过程可分为四步
- 客户端与服务端建立连接
- 客户端发生一个http协议指定格式的请求
- 服务器端接收请求后,响应一个http协议指定格式的响应
- 客户端将服务器的响应显示展现给用户
数据格式
请求格式
请求首行 请求头 空行 请求体
- 请求首行
- 请求头
- 请求体请求报文
响应状态码
用数字表示一串语言解释
# 1打头:消息通知
# 2打头:请求成功
# 3打头:重定向
# 4打头:客户端错误
# 5打头:服务器端错误
# 请求行 请求头 请求体
'''
POST / HTTP/1.1\r\n
Host: 127.0.0.1:8001\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
usr=abc&pwd=123
'''
- 响应报文
# 响应行 响应头 响应体
'''
HTTP/1.1 200 OK\r\n
Content-type:text/html\r\n
\r\n
Login Success
'''
- 修改返回数据,完善响应体
# 字符串
client.send(b'HTTP/1.1 200 OK\r\n')
client.send(b'\r\n')
client.send(b'Normal Socket Web')
# html代码,请求头要设置支持html代码
client.send(b'HTTP/1.1 200 OK\r\n')
client.send(b'Content-type:text/html\r\n')
client.send(b'\r\n')
client.send(b'<h1>Normal Socket Web</h1>')
# html文件(同级目录建立一个index.html页面)
client.send(b'HTTP/1.1 200 OK\r\n')
client.send(b'Content-type:text/html\r\n')
client.send(b'\r\n')
# 利用文件方式读取页面
with open('index.html', 'rb') as f:
dt = f.read()
client.send(dt)
- 修改接收数据,模拟后台路由
# 分析接收到的数据
data = client.recv(1024)
# 保证接收到的数据作为字符串进行以下处理
data = str(data, encoding='utf-8')
# 拆分出地址位
route = data.split('\r\n')[0].split(' ')[1]
# 匹配地址,做出不同的响应
if route == '/index':
with open('index.html', 'rb') as f:
dt = f.read()
elif route == '/login': # 新建login页面
with open('login.html', 'rb') as f:
dt = f.read()
else:
dt = b'404'
client.send(dt)
动静态网页
静态网页
数据是写死的,万年不变(哪怕改变了,也是认为直接修改)
动态网页
数据是实时获取的
eg:
1.后端代码动态获取当前时间
2.数据是从数据库查询出来的
jinjia2模板语法
专门用来处理后端数据与html页面的交互
模板语法(极其贴近python后端语法)
让你能够在html页面上 也能够用后端python语法来操作后端传递过来的数据
<p>{{ userDic }}</p>
<p>{{ userDic.username }}</p>
<p>{{ userDic['age'] }}</p>
<p>{{ userDic.get('hobby') }}</p>
<p>{{ userDic.get('hobby').0 }}</p>
<p>{{ userDic.get('hobby').1 }}</p>
<p>{{ userDic.get('hobby').2 }}</p>
{% for user_dic in user_list %}
<tr>
<td>{{ user_dic.id }}</td>
<td>{{ user_dic.username }}</td>
<td>{{ user_dic.password }}</td>
</tr>
{% endfor %}
模板的渲染 将后端传递给html文件的数据 在后端处理好 生成一个完整的html文件的过程
注意 模板的渲染是在后端完成的 跟前端没有关系
结合前端,自己写的后端框架 ,数据库(前端动态展示数据库数据)
四、框架演变
- 目录结构
part2
-- favicon.ico
-- index.html
-- manage.py
- manage.py
import socket
import pymysql
# 响应头
RESP_HEADER = b'HTTP/1.1 200 OK\r\nContent-type:text/html\r\n\r\n'
# 请求处理
def index():
# 以字节方式读取文件
with open('index.html', 'rb') as f:
dt = f.read()
return dt
def ico():
with open(favicon.jpeg, 'rb') as f:
dt = f.read()
return dt
def user():
# 数据库操作
conn = pymysql.connect(host='127.0.0.1', port=3306, db='django', user='root', password='root')
cur = conn.cursor(pymysql.cursors.DictCursor)
cur.execute('select * from user')
users = cur.fetchall()
print(users)
users = '''%d:%s
%d:%s''' % (users[0]['id'], users[0]['name'], users[1]['id'], users[1]['name'])
return users.encode('utf-8')
# 设置路由
urls = {
# 请求路径与请求处理函数一一对应
'/index': index,
favicon.jpeg: ico,
'/user': user
}
# 设置socket
def serve(host, port):
server = socket.socket()
server.bind((host, port))
print('start:http://' + host + ':' + str(port))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024)
data = str(data, encoding='utf-8')
print(data)
route = data.split('\r\n')[0].split(' ')[1]
resp = b'404'
if route in urls: resp = urls[route]() sock.send(RESP_HEADER) sock.send(resp) sock.close()# 启服务if __name__ == '__main__': serve('127.0.0.1', 8002)
五、项目演变
- 目录结构
03_proj
-- template
-- index.html
-- user.html
favicon.ico
start.py
urls.py
views.py
- index.html
<h1>{{ name }}</h1>
- user.html
<table border="1">
<tr>
<th>id</th>
<th>name</th>
<th>password</th>
</tr>
{% for user in users%}
<tr>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.password}}</td>
</tr>
{% endfor %}
</table>
- start.py
from wsgiref.simple_server import make_server
from urls import urls
def app(env, response):
print(env)
# 设置响应头
response("200 OK", [('Content-type', 'text/html')])
route = env['PATH_INFO']
print(route)
data = urls['error']()
if route in urls:
data = urls[route]()
# 返回二进制响应体
return [data]
if __name__ == '__main__':
server = make_server('127.0.0.1', 8003, app)
print('start:http://127.0.0.1:8003')
server.serve_forever()
- urls.py
from views import *
urls = {
'/index': index,
'/favicon.ico': ico,
'/user': user,
'error': error
}
- views.py
import pymysql
# 利用jinja2来渲染模板,将后台数据传给前台
from jinja2 import Template
def index():
with open('templates/index.html', 'r') as f:
dt = f.read()
tem = Template(dt)
resp = tem.render(name='主页')
return resp.encode('utf-8')
def ico():
with open('favicon.ico', 'rb') as f:
dt = f.read()
return dt
def user():
# 数据库操作
conn = pymysql.connect(host='127.0.0.1', port=3306, db='django', user='root', password='root')
cur = conn.cursor(pymysql.cursors.DictCursor)
cur.execute('select * from user')
users = cur.fetchall()
print(users)
with open('templates/user.html', 'r') as f:
dt = f.read()
tem = Template(dt)
resp = tem.render(users=users)
return resp.encode('utf-8')
def error():
return b'404'
Django的创建以及配置
基于第三方模块帮你撸
views.py 里面的放的是函数 我们管这些函数叫视图函数 视图层
urls.py 里面放的是 路由(后缀)与视图函数的对应关系 路由层
templates文件夹 里面放的全是html文件 模板层
1.三大主流web框架
python的三大主流框架
django 大而全 自带的组件和功能非常非常多 类似于航空母舰
不足之处:写小项目的时候 可能会比较笨重(大材小用)
flask 小而精 短小精悍 自带的组件和功能特别特别少 类似于游骑兵
基本全部依赖于第三方组件
不足之处:受限于第三方模块的影响比较大
如果将flask所有第三方模块加起来 能够直接盖过django
tornado 异步非阻塞 这个框架甚至可以用来开发游戏服务器
a:socket部分
b:路由匹配
c:模板语法
django:
a用的别人的wsgiref(django默认的)
b自己写的
c自己写的
flask:
a用的别人的werkzeug
b自己写的
c用的别人的jinja2
Tornado:
a,b,c都是自己写的
2.Django 安装
2.1 注意事项
1.计算机名称不能有中文
2.python解释器不要使用3.7版本 推荐使用版本3.4~3.6
3.一个pycharm窗口 只能跑一个项目
2.2 版本问题
django版本以1.11.11为主(1.11.9~1.11.13)
2.3 安装是否成功
命令行敲 django-admin
2.4 目录设置
'''
安装:pip3 install django==1.11.x
查看版本号:django-admin --version
新建项目:1.前往目标目录 2.django-admin startproject proj_name
proj_name:项目目录,包含项目最基本的一些配置
-- __init__.py:模块的配置文件
-- settings.py:配置总文件
-- urls.py: url配置文件,django项目中的所有页面都需要对其配置url地址
-- wsgi.py:(web server gateway interface),服务器网关接口,python应用与web服务器直接通信的接口
templates:模板文件夹,存放html文件的(页面),支持使用Django模板语言(DTL),也可以使用第三方(jinja2)
manage.py:项目管理器,与项目交互的命令行工具集的入口,查看支持的所有命令python3 manage.py
'''
3. Django使用
3.1 cmd命令行创建
1.创建django项目
切换到相应目录
django-admin startproject 项目名(例如mysite)
2.启动django项目
切换到项目文件夹下 cd/ mysite
python manage.py runserver
python manage.py runserver 127.0.0.1:8080
3.创建应用(django支持多app开发)
python3 manage.py startapp "应用名app01"
ctrl+c
停止cmd中的项目服务
注意
1.不会自动帮你创建templates文件夹
2.配置文件中不会自动帮你书写templates文件路径
3.2 pycharm中创建
新建django的 NewProject 然后点击run启动 自动跳转
- 创建应用时,可以使用简便方式
使用tool可以直接输入创建指令
Tools >>> run manage.py task
-
一定要确保同一个端口,同一时间只能启动一个Django
-
配置文件中针对templates文件夹的路径 如果是空的需要你手动配置
如果找不到templates文件夹,检查setting中TEMPLATES是否正确
'DIRS': [os.path.join(BASE_DIR, 'templates')]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
3.app应用的创建与介绍
创建的app需要在django配置文件中注册方可生效,每个app都有其独特的功能
app的创建
python manage.py startapp 'app名app01'
app的概念
django是一个以开发app为主要功能的web框架
app就是application应用的意思
一个空的django本身没有任何作用 仅仅是为app提高前期的环境配置
你可以根据功能的不同 开发多个app
一个app对应一个具体的功能模块
用户相关的功能 用户相关的app
订单相关的功能 订单相关的app
商品相关的功能 商品相关的app
- Django是面向应用开发,在应用中完成具体的业务逻辑
- 什么是应用app: 就好比项目中的一个功能模块,一个项目可以拥有多个功能模块,但至少得有一个,Django称之为app
- 如何创建app(在项目目录下):python3 manage.py startapp
app内文件
- migrations:数据迁移(移植)模块,内容都是由Django自动生成
__init__.py
- admin.py:应用的后台管理系统配置
- apps.py:django 1.9后,本应用的相关配置
- models.py:数据模型模块,使用ORM框架,类似于MVC模式下的Model层
- tests.py:自动化测试模块,可以写自动化测试脚本
- views.py:执行相应的逻辑代码模块
注册
创建好的app需要在Django文件中注册方才有效
settings中配置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 简便写法
'app01'
# 最完整的写法
'app01.apps.App01Config'
]
编辑配置可以更改端口
4.Django文件功能
Django项目名
4.1 项目同名的文件夹
settings.py 暴露给用户可以配置的配置文件
urls.py 路由与视图函数对应关系
manage.py django的入口文件
4.2 应用名文件夹
migrations文件夹 所有数据库相关的操作记录
admin.py django admin后台管理
apps.py 注册app使用
models.py 放所有数据库相关的模型类
tests.py 测试文件
views.py 处理业务逻辑的视图函数
5.Django必会三板斧
1.HttpResponse
返回字符串
return HttpResponse ("一列字符串")
2.render
返回HTML文件,可以给html页面传值
def login(request):
user_dic = {'username':'jason','password':'123'}
return render(request,'login.html',{'xxx':user_dic})
3.redirect
重定向
- 直接写你本网站的路径后缀
- 也可以全路径
def home(request):
# return redirect('/login') # 重定向
return redirect('https://www.baidu.com') # 重定向
注意
Django默认是重新启动的
重启机制
内有检测机制 实时检测所有文件的变化
有时候会产生 你代码还没写完 就自动重启报错的情况 不用管
每次写完代码之后 自己手动重启
5.启动项目
1.终端
# 终端: python3 manage.py runserver 127.0.0.1:8801
2.pycharm创建启动项目
- 创建Django
- 选择项目目录(从项目目录开始,目录文件夹及子文件夹不要出现中文,保证电脑名字不能为中文)
- 配置默认模板语言,模板路径,app名
- 启动
生命周期
- 浏览器发送请求
- wsgi服务器接收到请求,将请求解析交给Django
- Django中间件过滤请求信息,交给路由
- 路由完成业务逻辑的分发,到指定app下views中指定的视图函数
- 视图函数完成具体的业务逻辑,返回响应结果
- 将处理结果通过服务器返回给浏览器