jdango框架基础一
jdango框架
软件开发的架构:
c/s架构
b/s架构(本质还是c/s)
web后端
需求
1.根据用户输入不同的后缀返回不同的内容
从符合http协议格式的数据中获取用户输入的后缀
不足之处
1.socket代码是我们自己写的
2.http数据也是我们自己处理的
HTTP的协议
1.四大特性:
-基于请求响应
-基于TCP/IP作用于应用层之上的协议
-无状态
本协议只要访问结束就会清零,下次还是访问还是新状态
-无连接
2.数据格式
请求格式:
请求首行(请求方式,协议版本)
请求头(一堆kv键值对)
中间要空一行‘
请求体
3.响应状态码
用数字来表示一堆提示性的信息
各个公司可以自己定义自己的响应状态码
1XX:服务端已经成功接收了客户端的数据正在处理,你可以继续提交
2XX:200 请求成功 服务端已经返回你想要的数据
3XX:重定向(原来想访问A 但是内部会自动给你转到B上面)
4XX:404 请求资源不存在,403你不具备请求该资源的条件
5XX:500服务端内部的错误
需求
1.根据用户输入不同的后缀返回不同的内容
从符合http协议格式的数据中获取用户输入的后缀
不足之处
1.socket代码是我们自己写的
2.http数据也是我们自己处理的
import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
"""
请求首行
b'GET / HTTP/1.1\r\n
请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
请求体
'
"""
while True:
conn, addr = server.accept()
data = conn.recv(1024)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
# print(data)
data = data.decode('utf-8') # bytes变成一串字符串
target_url = data.split('\r\n')[0].split(' ')[1]
# 判断url返回响应的内容即可
if target_url == '/index':
# conn.send(b'index')
with open(r'D:\上海校区python13期视频\day49\01 demo.html','rb') as f:
conn.send(f.read())
elif target_url == '/login':
conn.send(b'login')
else:
conn.send(b'404 error')
conn.close()
3.基于wsgiref模块撸
根据功能的不同拆分成不同的文件
用户在浏览器窗口输入url之所以能够获取到相应的资源
是因为后端早已经开设了相应的资源接口
基于wsgiref模块以及文件拆分的特点
只要你想要开设新的资源
1.先在urls文件中写url与函数的对应关系
2.再去views文件中写对应的函数
urls.py:路由与视图函数的对应关系
views.py:里面就是放的一堆视图函数(视图函数可以是函数也可以是类)
templates文件夹:里面放的就是一堆html文件(模板文件夹)
动静态网页
静态网页
数据是写死的 万年不变
动态网页
数据是动态获取的
eg:
1.获取当前时间
2.从数据库中获取数据
需求
1.你给我写一个对应关系 一旦访问立刻展示当前访问的时间
2.后端有一个用户字典 你需要将该字典传递给html页面 并且在该页面上还可以将传递过来的数据当成字典数据进行获取值的操作
jinja2模块
提供了一个可以在html页面上书写类似于python后端的代码 来操作数据(模板语法)
pip3 install jinja2
flask框架模板语法使用的就是jinja2模块,所以你只要下了flask框架 就会自动下载jinja2
模板语法(jinja2模板语法非常贴近python语法 但是并不是所有的框架使用的都是jinja模板语法)
{{ 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 %}
{{ user_dict.id }}
{{ user_dict.name }}
{{ user_dict.hobby }}
{% endfor %}
获取数据库中数据 展示到前端页面
基于wsgiref模块
from wsgiref.simple_server import make_server
from views import * #*代表的是导入所有的信息
from urls import urls
def run(env,response):
"""
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return: 浏览器能够接受的内容
"""
response('200 OK',[])
# print(env) # 大字典 里面的PATH_INFO参数就是用户输入的后缀
target_url = env.get('PATH_INFO')
# if target_url == '/index':
# # 一堆逻辑判断
# return [b'index']
# elif target_url == '/login':
# return [b'login']
# 先定义一个变量 用来存储可能匹配到的函数名
func = None
# 1 for循环获取一个个的url与函数对应关系的元组
for url in urls: # url = (),(),()
# 2 判断当前用户访问的url与元组第一个元素是否一致
if target_url == url[0]:
# 3 如果相等 说明有对应的后端逻辑代码 将匹配到的函数名赋值给func
func = url[1]
# 4 一旦用户匹配上了响应的url 应该立刻结束当前for循环了 因为没有意义
break
# 针对func是否有值 还需要判断
if func:
# 匹配上了 加括号直接调用
res = func(env)
else:
# 匹配404逻辑代码
res = error(env)
return [res.encode('utf-8')] # 这个里面的res是view里面返回的,返回函数的返回值给浏览器 并且编码成bytes
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
# 监听127.0.0.1:8080 一旦有客户端来访问 会立刻将make_server第三个参数加括号调用执行
server.serve_forever() # 启动服务端
urls
from views import *
urls = [
('/index',index),
('/login',login),
('/xxx',xxx),
('/get_time',get_time),
('/get_user',get_user),
('/get_info',get_info)
]
views
def index(env):
return 'index'
def login(env):
return 'login'
def error(env):
return '404 error'
def xxx(env):
return 'xxx'
import time
def get_time(env):
# 该函数需要返回一个html页面
current_time = time.strftime('%Y-%m-%d %X')
# 文件操作 读取html文件
with open(r'D:\上海校区python13期视频\day49\templates\02 get_time.html','r',encoding='utf-8') as f:
data = f.read() # html文件内容 字符串
data = data.replace('gfdgsfdgfdsgsfdgsfdgsfdgsdg',current_time) # 利用字符串的替换
return data
from jinja2 import Template
def get_user(env):
user_dict = {'username':'jason','password':123,'hobby':['read','study','run']}
with open(r'D:\上海校区python13期视频\day49\templates\03 get_user.html','r',encoding='utf-8') as f:
data = f.read()
temp = Template(data)
res = temp.render(xxx=user_dict) # 将user_dict传递给html页面 在页面上通过变量名xxx就能够获取到user_dict
return res
import pymysql
def get_info(env):
conn= pymysql.connect(
host= '127.0.0.1',
port= 3306,
user= 'root',
password= '123',
database= 'mydjango',
charset= 'utf8',
autocommit = True #自动提交给mysql确认
)
cursor= conn.cursor(cursor=pymysql.cursors.DictCursor)#产生一个游标对象
#cursor= pymsql.cursors.DictCursor 将查询的结果 做一个字典的形式返回
sql= 'select * from user_info'
cursor.execute(sql)#执行sql语句
data = cursor.fetchall() #获取查询结果的所有数据
##结果是是[{} ,{},{}]
#讲列表套字典的结果数据,直接传递给html的页面上
with open(r'','r', encoding='utf-8') as f:
res = f.read()
#利用jinja2模块
tmp= Template(res)
#利用对象render的方法,将数据直接传递给html页面
res= tmp.render(xxx=data)
return res
get_user.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{{ 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>
</body>
</html>
get_info.hrml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<h2 class="text-center">数据展示</h2>
<div class="col-md-8 col-md-offset-2">
<table class="table-hover table table-striped">
<thead>
<tr>
<th>id</th>
<th>username</th>
<th>hobby</th>
</tr>
</thead>
<tbody>
<!-- xxx = [{},{},{},{}]-->
{%for user_dict in xxx %}
<tr>
<td>{{ user_dict.id }}</td>
<td>{{ user_dict.name }}</td>
<td>{{ user_dict.hobby }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
get_time.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
gfdgsfdgfdsgsfdgsfdgsfdgsdg
</body>
</html>
4.获取数据库中数据 展示到前端页面
1.路由与视图函数对应关系
2.视图函数
3.模板文件夹
4.模板语法(是在后端实现的 前端根本不识别)
web框架
python三大主流web框架
django
大而全 自身携带的组件和功能特别特别多 就类似于航空母舰
不足之处:笨重
当你的功能不多 不需要使用很多其他功能
flask(源码600多行 请求上下文 应用上下文)
小而精 自身携带的组件和功能特别特别少 就类似于游骑兵
虽然自身功能比较少 但是第三方支持该框架的模块特别特别多
如果你将flask第三方模块全部叠加起来 甚至可以超过django
不足之处:受限于第三方模块
tornado
异步非阻塞
天然支持高并发 甚至可以用它来开发游戏服务器
django框架
1.注意事项
1.计算机名称不能有中文
2.项目文件名也不要用中文
3.一个pycharm窗口就是一个单独的完整的项目
2.版本问题
1.X
2.X
推荐你使用1.X版本里面的
1.11.09~1.11.13
如果你已经按照过不需要手动卸载 重新安会自动先卸载之前的版本再安装
3.安装
pip3 install django==1.11.11
4.测试是否安装成功
命令行输入django-admin
如何创建django项目
1.命令行
1.创建django项目
django-admin startproject mysite(项目名)
效果:创建一个mysite的文件夹
mysite
-mysite
--__init__.py
--settings.py
--urls.py
--wsgi.py
-manage.py
2.启动django项目(先切换到项目目录下)
python3 manage.py runserver # django默认的端口号是8000
3.创建具有独立功能的app 通常情况下应该做到建明制衣
python manage.py startapp app01
app01
--migrations文件夹
--__init__.py
--admin.py
--apps.py
--models.py
--tests.py
--views.py
"""
1.使用命令行创建的django项目是不会自动创建templates摸版本文件夹 你只能自己手动创建
2.命令行创建的django项目不但没有templates文件夹配置文件中也没有填写路径
而pycharm创建的会自动添加
"""
2.pycharm快捷创建
app的概念
application 应用
django其实是一个专注于开发app的web框架
一个空的django项目就类似于是一所大学
app就类似于大学里面的各个学院
每个app其实就类似于不同的功能模块
购物网站
用户相关 user
用户相关的app
订单相关 order
订单相关的app
投诉相关 tousu
投诉相关的app
不同的功能模块推荐使用不同的app去开发
django支持多app
python解释器版本不要使用3.7
推荐你使用3.4~3.6
django主要文件功能
mysite
-mysite
--init.py
--settings.py 项目配置文件
--urls.py 路由视图函数对应关系 项目的总路由
--wsgi.py
-manage.py
app01
--migrations文件夹 数据库改动记录
----init.py
--init.py
--admin.py django后台管理
--apps.py 注册app相关
--models.py 模型类(ORM)
--tests.py 测试文件
--views.py 视图函数()
app02
--migrations文件夹 数据库改动记录
----init.py
--init.py
--admin.py django后台管理
--apps.py 注册app相关
--models.py 模型类(ORM)
--tests.py 测试文件
--views.py 视图函数()
db.sqlite3 django自带的一个小型用于本地测试的数据库(对日期格式的数据不是很敏感)
容易犯的错误
1.代码修改了始终没有效果
1.在同一个端口起了多个服务 一直跑的是最开始的那个服务
2.浏览器缓存问题
***创建app之后一定一定要先去setting文件中注册
django能够自动重启 但是它的重启机制
只要检测到你的代码有变化 在一定的时间间隔内就会自动重启
所以有时候可能会出现 你代码还没写完 就已经自动重启了
django小白必会三板斧
HttpResponse
返回字符串
render
返回html页面 并且可以给html页面传数据
模板的渲染(将数据在后端按照模板语法放入html对应的位置)
redirect
重定向
def index(request):
return HttpResponse('你好啊 小妹妹')
def login(request):
return render(request,'login.html',{'user_dict':{'username':'jason','password':123},'userxxx':'hello world'})
def home(request):
# return redirect('https://www.mzitu.com')
return redirect('/index')
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.js"></script>
</head>
<body>
<p>我的脑力正在不断的提高 非常棒的一件事情</p>
{{ user_dict }}
{{ user_dict.name }}
</body>
</html>