基础

# HTTP响应状态码
10X:服务端已经接受到你的数据了 你可以继续提交数据进行下一步操作
20X:请求成功(200)
30X:重定向(301,302)
40X:请求错误(404)
50X:服务端错误(500) # GET请求与POST请求
GET请求:获取页面资源
POST请求:朝服务端发送数据(让服务端校验该数据)

一、Web框架本质

  所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端

根据不同的路径返回不同的内容

  可以写几个简单页面,然后通过http://127.0.0.1:8080/页面名称  来访问对应的页面测试

import socket

server = socket.socket()  # 默认是TCP协议
server.bind(('127.0.0.1',8080)) # 绑定IP端口
server.listen(5) # 监听 半链接池:保护计算机安全 while True:
conn, addr = server.accept() # 等待连接
data = conn.recv(1024) # 接收客户端信息
# 遵循HTTP协议,给回应的消息加上响应状态行
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
res = data.decode('utf-8')
current_path = res.split('\r\n')[0].split(' ')[1] # 字符串切割,获取路径
# print(current_path)
# 根据不同的路径返回不同的内容
if current_path == '/index':
# conn.send(b'index')
with open('templates/111.html','rb') as f:
conn.send(f.read())
elif current_path == '/login':
conn.send(b'login')
else:
conn.send(b'404')
conn.close()

浏览器访问页面请求信息:

  HTTP协议主要规定了客户端和服务器之间的通信格式

  响应相关信息可以在浏览器调试窗口的network标签页中看到。可以根据view信息切割获得需要请求的页面

请求首行
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.142 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,en;q=0.8\r\n
Cookie: csrftoken=3vPenhmlRQb8Tvl4okwYM0OZpDCl3P7rbxvfpRDOHJy1zUApw89ugxM6OZSxhIBM\r\n
\r\n
请求体
'
http://127.0.0.1:8080/index
view展开:

根据不同的路径返回不同页面请求---函数版

import socket

sk = socket.socket()
sk.bind(('127.0.0.1',8001))
sk.listen() # 将不同的内容部分封装成函数
def index(url):
# 读取index.html页面内容
with open("index.html",'rb',encoding="utf-8") as f:
s = f.read()
# 返回字节数据
return bytes(s,encoding="utf-8") def login(url):
with open("login.html",'rb',encoding="utf-8") as f:
s = f.read()
return bytes(s, encoding="utf-8") list1= [
("templates/111.html","/index"),
("templates/login.html",'/login'),
] while True:
# 等待连接
conn,add = sk.accept()
data = conn.recv(1024) # 接收客户端发来的消息
# 从data 中获取路径
data = str(data,encoding='utf-8') # 把收到的字节类型数据转换成字符串
print("data>>>",data)
# 按\r\n切割,url是从浏览器发过来的消息中分离出来的访问路径
url = data.split("\r\n")[0].split(' ')[1]
print("url>>>>",url)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n') #遵循http协议,所以回复的消息也要加状态行
# 根据不同的路径返回不同内容,reponse是具体的响应体
func = None
for i in list1:
if i[0].split("/")[1] == url:
func = i[1]
break
# print("func>>>",func)
if func:
reponse = func(url)
else:
reponse = b"404 not found!" conn.send(reponse)
conn.close() # 还有点问题//TODO

 二、服务器程序和应用程序 

  对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。
  服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。

  应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。

  WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦

  常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。

1.wsgiref 模块

  利用wsgiref模块来替换我们自己写的web框架的socket server部分

# 未拆分前代码
# http://127.0.0.1/index访问对应的名称到对应的页面
from wsgiref.simple_server import make_server def index():
return 'index' def reg():
return 'res' def login():
return 'login' def error():
return '404' urls = [
('/index',index),
('/reg',reg),
('/login',login),
] def run(env,reponse):
reponse('200 OK', []) # 固定格式
print(env) # 将http格式的数据处理完毕,形成一个字段给你调用
current_path = env.get('PATH_INFO')
# if current_path == '/index':
# return [b'index']
func = None
for url_tuple in urls:
if current_path == url_tuple[0]:
func = url_tuple[1] # 如果路由匹配上了,就回去对应的函数
break
if func:
res = func()
else:
res = error()
return [res.encode('utf-8')] if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run) # 一直监听地址,只要有请求,就会给最后的函数或对象调用:run()执行
server.serve_forever()

# urls.py 存放访问链接后的页面

from views import *
urls = [
('/index',index),
('/reg',reg),
('/login',login),
] # views.py 存放访问页面函数
def index():
return 'index' def reg():
return 'res' def login():
return 'login' def error():
return '404' # wsgiref.py存放启动
from wsgiref.simple_server import make_server
from urls import urls
from views import * def run(env,response):
response('200 OK', []) # 固定格式 不需掌握
print(env) # 将http格式的数据处理完毕 形成一个字段给你调用
current_path = env.get('PATH_INFO')
func = None
for url_tuple in urls:
if current_path == url_tuple[0]:
func = url_tuple[1] # 如果路由匹配上了 就回去对应的函数
break
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')] if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever()

拆分后代码

根据拆分后的代码,如果需要再添加访问页面,只需要在urls.py(路由与视图函数的映射关系)和views.py(视图函数)中增加对应的链接和函数就可以

2.动静态页面

  静态网页:数据是写死的,一直不变

  动态网页:数据实时获取的,一直在改变(eg:数据库的数据或当前时间)

2.1获取时间并显示在页面上:

# 在上面拆分代码的基础上
# urls.py增加
urls = [
('/index',index),
('/reg',reg),
('/login',login),
('/get_time',get_time),
] # 对象视图views.py里增加函数
import time
def get_time():
with open('templates/show_time.html','r',encoding='utf-8') as f:
data = f.read()
current_time = time.strftime('%Y-%m-%d %X')
res = data.replace('timekkk',current_time) # 字符串替换
return res 然后运行wsgiref.py就可以看到页面上显示动态的时间了,每次刷新时间都会变化

2.2 给前端传字典并且字典可以取值

# urls.py中新增对应访问路径
from view2 import * urls2 = [
('/index', index),
('/reg', reg),
('/login', login),
('/get_time', get_time),
('/get_user', get_user),
] # views.py中新增对应函数
from jinja2 import Template def get_user(env):
user_dict = {'username': 'simon', 'password': '123'}
with open('templates/get_user.html', 'r', encoding='utf-8') as f:
data = f.read()
tmp = Template(data) # 实例化产生对象
res = tmp.render(data=user_dict) # 将user_dict传递给前端页面,前端页面用过变量名data就能够拿到user_dict字典
return res # html页面body中设置
{#传data这里就写data#}
{{ data }}
{#获取账号密码#}
<p>{{data.username}}</p>
<p>{{data['password']}}</p>
<p>{{data.hobby.0}}</p>
<p>{{data.hobby.1}}</p>

模板渲染(雏形)

  后端产生的数据直接传递给前端页面,前端页面获取数据通过模板语法展示

模板语法:

  {{}} 获取后端传递的数据,通过变量名(变量名相关的)

  {%%} 与逻辑相关的使用这个语法

  jinja2模板语法极为接近后端python语法

{{ data }}
<p>{{data.username}}</p>
<p>{{data['password']}}</p>
<p>{{data.hobby.0}}</p>
<p>{{data.hobby.1}}</p>
 

逻辑相关:

{%for user_dict in user_list%}
<tr>
<td>{{user_dict.id}}</td>
<td>{{user_dict.username}}</td>
<td>{{user_dict.password}}</td>
</tr>
{%endfor%}

2.3 数据库取值页面显示

#urls2.py
from view2 import * urls2 = [
('/get_data',get_data),
] # view2.py 新增函数
from jinja2 import Template
import pymysql def get_data(env):
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '123',
database = 'test',
charset = 'utf8',
autocommit = True
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from userinfo')
res = cursor.fetchall()
with open('templates/get_data.html','r',encoding='utf-8') as f:
data = f.read()
tmp = Template(data)
res1 = tmp.render(user_list = res)
return res1 # simple_server.py模块,和之前的没什么变化
from wsgiref.simple_server import make_server
from urls2 import urls2
from view2 import * def run(env,reponse):
reponse('200 OK', []) # 固定格式
print(env) # 将http格式的数据处理完毕,形成一个字段给你调用
current_path = env.get('PATH_INFO')
# if current_path == '/index':
# return [b'index']
func = None
for url_tuple in urls2:
if current_path == url_tuple[0]:
func = url_tuple[1] # 如果路由匹配上了,就回去对应的函数
break
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')] if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run) # 一直监听地址,只要有请求,就会给最后的函数或对象调用:run()执行
server.serve_forever() # get_data.html前端页面代码
# body内容
<table>
<thead>
<tr>
<th>id</th>
<th>username</th>
<th>password</th>
</tr>
</thead>
<tbody>
{%for user_dict in user_list%}
<tr>
<td>{{user_dict.id}}</td>
<td>{{user_dict.username}}</td>
<td>{{user_dict.password}}</td>
</tr>
{%endfor%}
</tbody>
</table>

数据库取值

2.4 web服务渲染流程

  根据早上的流程,我们可以划出下面这个图

2.5 web框架

python主流三大框架:

   a.socket服务

   b:路由与视图函数映射关系

   c:模板渲染
  django:大而全 类似航空母舰      a.用的别人的 wsgiref 上线之后会换成uwsgi;默认并发1000多,自己可以加nginx之类处理      b.自己写的      c.自己写的
  flask:小而精,轻量级框架   a用的别人的 werkzeug
  b自己写的
  c用的别人 jinja2
  tornado:异步非阻塞     三者都是自己写的

三、Django简介

1.Django安装与注意事项

# 主意事项
1.计算机名称不能含有中文
2.一个pycharm窗口就是一个工程(项目)
3.项目文件夹不要有中文 # ps:django版本: django 1.X(现在用的版本是这个1.11.11) # 安装
pip3 install django
# 或pycharm直接安装,可以指定版本specify version
# 如果已经安装了高版本需要降低版本:pip3 uninstall django,然后重新指定安装:pip3 install django ===1.11.20 或pycharm指定版本安装 # 查看djiango是否安装成功
命令行界面:django-admin # 命令行创建django项目
django-admin startproject 项目名
ps:创建一个应用面的文件夹,里面有一个跟应用名同名的文件夹和一个manage.py的文件 # 命令行创建应用
django-admin startapp 应用名 # application
一个django项目 可以有多个应用,django是一款开发应用的web框架
django项目就类似是一所大学,而里面的应用就类似于一个个学院 # 命令行启动项目
python manage.py runserver
启动成功后浏览器可以访问:http://127.0.0.1:8000和http://127.0.0.1:8000/admin ps:命令行创建django项目不会自动新建templates文件夹,并且settings.py配置文件(TEMPLATES 列表中DIRS)不会自动写templates文件夹路径,所以都需要手动添加[os.path.join(BASE_DIR,'templates')]
如下图: # pycharm创建
项目:File-->New Project-->Django-->Location(创建项目)-->More Settings创建应用--->Application name:应用名
在pycharm的命令行中创建应用:Tools-->Run manage.py TASK-->startapp 应用名
应用创建后需要再settings.py中注册应用INSTALLED_APPS里添加 启动后可以访问:http://127.0.0.1:8000 # 注意:
1 在django中创建的应用必须去settings文件中注册才能生效,否则django不识别
2 确保不要端口冲突

2.Django项目目录结构

项目名
应用名文件夹
migrations文件夹
数据库迁移记录
admin.py
django admin后台管理相关
models.py
模型类
views.py
视图函数 项目同名文件夹
settings.py
django暴露给用户可配置的配置文件
urls.py
路由与视图函数映射关系
templates
所有的html文件
manage.py
django入口文件

3.Django 必会三板斧

# django小白必会三板斧

# HttpResponse:返回字符串
# views.py
from django.shortcuts import render,HttpResponse,redirect
def index(request):
return HttpResponse("Hello Django index") # render:返回html页面
def login(request):
return render(request,'login.html') # redirect:重定向
def home(request):
return redirect('https://www.baidu.com') # urls.py配置文件中加对应访问路径
from django.contrib import admin
from django.urls import path
from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('login/', views.login),
path('home/', views.home),
]

4.静态文件配置

# 动态实时监测到前缀的变化
login.html
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
{% load static %}
<link href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}" rel="stylesheet">
<script src={% static "bootstrap-3.3.7/js/bootstrap.min.js" %}></script> </head> #用上述方法settings.py中接口前缀随便修改,也不需要修改html中的对应前缀 # settings.py
# 接口前缀:要想访问静态资源必须static打头:
# <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
STATIC_URL = '/static/'
# 新增文件放置路径
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
os.path.join(BASE_DIR,'static1'),
os.path.join(BASE_DIR,'static2'),
]

例:登录功能简单实现

# form表单默认是get请求
get请求携带的参数是拼接在url后面的以?开头&链接,默认method方式为Get
ps:get请求可以携带参数 但是参数的大小有限制 最大4KB,并且是明文的
http://127.0.0.1:8000/login/?username=simon&password=123 # 如果改为method改为post提交,需要将settings.py中一行注释,否则会报403错误:
# 'django.middleware.csrf.CsrfViewMiddleware', # 跨站请求伪造 获取用户输入的框 都必须要有name属性 action参数有三种写法
1.什么都不写 默认往当前页面的url地址提交
2.只写路由后缀(******)
<form action="/login/" method="post">
3.写全路径
<form action="https://www.baidu.com" method="post">
# 数据后端获取

#前端
<form action="" method="post">
<p>username:<input type="text" class="form-control" name="username"></p>
<p>password:<input type="password" class="form-control" name="password"></p>
<p>篮球<input type="checkbox" name="xxx" value="basketball"></p>
<p>足球<input type="checkbox" name="xxx" value="football"></p>
<p>冰球<input type="checkbox" name="xxx" value="ice"></p>
<input type="submit" class="btn btn-success pull-right">
</form>
# views.py:获取访问login页面的method以及post提交的数据
def login(request):
print(request.method) # 获取当前请求方式
if request.method == 'POST':
# 获取post请求提交的数据
print(request.POST)
# get请求默认拿列表最后一个值:如-获取到2个username,取值永远拿最后一个元素
username = request.POST.get('username')
password = request.POST.get('password') # 还可以在后面增加判断账号密码判断,以后通过数据库来判断传递的账号密码
     if username == "simon" and password == "123":
      return redirect("http://www.xiaohuar.com")
     return "xxxxxxx"
hobby = request.POST.getlist('xxx')
print(hobby,type(hobby))
print(username,type(username))
print(password, type(password))
return render(request,'login.html') # 结果:
POST
<QueryDict: {'username': ['simon'], 'password': ['123'], 'xxx': ['basketball', 'football', 'ice']}>
['basketball', 'football', 'ice'] <class 'list'>
simon <class 'str'>
123 <class 'str'>

python之Djiango框架简介的更多相关文章

  1. Python 各种测试框架简介(三):nose

    转载:https://blog.csdn.net/qq_15013233/article/details/52527260 摘要 这里将从(pythontesting.net)陆续编译四篇 Pytho ...

  2. Python 各种测试框架简介

    转载:https://blog.csdn.net/yockie/article/details/47415265 一.doctest doctest 是一个 Python 发行版自带的标准模块.本篇将 ...

  3. python爬虫----scrapy框架简介和基础应用

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以 ...

  4. Selenium3+python自动化010-UnitTest框架简介和单元测试框架使用

    一.UnitTest介绍 unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过, ...

  5. djiango框架推导过程,jinja2模板语法,jiango简介,基本操作命令

    djiango框架推导过程,jinja2模板语法,jiango简介,基本操作命令 一.web框架前戏 web 框架可以理解为是基于会联网的web服务端>>>socket服务端 1.w ...

  6. python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介

    内容目录: JSONP应用 瀑布流布局 组合搜索 多级评论 tornado框架简介 JSONP应用 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. ...

  7. Python学习(三十)—— Django框架简介

    转载自:http://www.cnblogs.com/liwenzhou/p/8296964.html Django框架简介 一.MVC框架和MTV框架(了解即可) MVC,全名是Model View ...

  8. Appium+python自动化(三十八) - Appium自动化测试框架综合实践 - 框架简介-助你冲击高薪,迎娶白富美(超详解)

    简介 好久没有更新博客了,博友们是不是有点等不及了.不好意思啊,中秋节过后太忙了,这篇是好不容易抽点零碎时间写的.从这一篇开始小伙伴或者童鞋们,就跟随宏哥的脚步,一步步的从无到有,从0到1的搭建一个完 ...

  9. python 之 Django框架(Django框架简介、视图装饰器、request对象、Response对象)

    12.33 Django框架简介: MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器( ...

  10. python主流框架简介和Django框架的使用

    目录 一.手撸简易web框架 二.动静态网页 1. 静态网页 2. 动态网页 三.jinja2模板语法 1. jinja2的作用 四.python主流web框架 1. django 3. tornad ...

随机推荐

  1. KingbaseES 数据插入更新操作

    数据库使用过程中,经常会遇到一种场景:业务系统对数据进行dml操作,当数据库中数据不存在时,将数据做为新记录插入到表中,当数据库中数据存在时,对现有数据进行更新操作. 下面介绍KingbaseES中对 ...

  2. KingbaseES V8R6 集群运维案例--麒麟系统bug导致sys_monitor.sh无法启动集群

    案例说明: 麒麟信安操作系统,在部署了KingbaseES V8R6集群后,sys_monitor.sh在启动集群时,启动数据库服务失败,导致集群无法正常启动.后连接现场分析发现,此环境只要通过ssh ...

  3. 分享本人依照NOI大纲整理的CSPJ复习资料

    2023 CSP-J 复习文件 考纲 复习好 : 基础知识与编程环境 难度 计算机的基本构成 计算机的组成及功能 - 知乎 (zhihu.com) 操作系统的基本概念与常见操作 操作系统基础知识大汇总 ...

  4. MybatisPlus的那些坑

    1.实体类属性会被错误解析,需要加上注解@TableField @TableField("front_of_id_card") //身份证正面 private String fro ...

  5. #Kruskal重构树,Dijkstra,倍增#洛谷 4768 [NOI2018]归程

    题目传送门 分析 首先Dijkstra是必需的(关于SPFA,它死了233) 无向图,所以先求出1号节点到所有点的距离,然后肯定希望起点能驾驶到离一号点最短的汽车可到的地方 但是怎么办,考虑海拔大的边 ...

  6. Pyside2简单案例

    代码: from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit app = QAppl ...

  7. 可视化库 pygal 生成png中文乱码

    解决方法:设置style,style中设置中文字体 代码如下: import pygal from pygal.style import Style import cairosvg style = S ...

  8. MogDB/openGauss访问控制简介

    MogDB/openGauss 访问控制简介 SQL 可以针对不同的数据库对象赋予不同的权限,这样就可以限制用户对数据的不必要访问,提高数据访问的安全性.常见的 SQL 权限如下: SELECT/UP ...

  9. 《深入理解Java虚拟机》读书笔记:内存分配策略

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存.关于回收内存这一点,我们已经使用了大量篇幅去介绍虚拟机中的垃圾收集器体系以及运作原理 ...

  10. 一步一步实现 .NET 8 部署到 Docker

    一.前言 本文仅针对操作系统为 CentOS 8 的环境下部署方法进行讲述.如有需要,后续将在其他文章中进行其他系统下的部署方式讲解. 二.准备工作 确保服务器已安装 docker. 可以通过命令 d ...