手写web框架

# coding:utf8

import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5) # data 中的信息
"""
请求首行,表明请求方式以及遵循的http协议版本
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/78.0.3904.97 Safari/537.36\r\n
Sec-Fetch-User: ?1\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
Sec-Fetch-Site: none\r\n
Sec-Fetch-Mode: navigate\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: csrftoken=aOZSalMQkKGbzstfjcw3O9sDoegdywL8AD7PzhidAyx3tXShN7oQtxN1MMnS6GVX\r\n
\r\n(******)
请求体 '
"""
while True:
conn, addr = server.accept() # 阻塞态
data = conn.recv(1024)
# print(data)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
data_str = data.decode('utf-8')
current_path = data_str.split('\r\n')[0].split(' ')[1]
print(current_path)
if current_path == '/index':
# conn.send(b'index')
with open(r'01 纯手撸的前端页面.html','rb') as f: # 基于网络传输,所以用'rb'
conn.send(f.read())
elif current_path == '/login':
conn.send(b'login')
else:
conn.send(b'404 error')
conn.close()
<!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 rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head>
<body>
<h1>你好呀,大兄弟!</h1>
<img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2973069531,657782944&fm=26&gp=0.jpg" alt="图片不存在!"> </body>
</html>

基于wsgiref模块写web服务端框架

基于第三方模块写web:

views.py 里面的放的是函数 我们管这些函数叫视图函数 视图层

urls.py 里面放的是 路由(后缀)与视图函数的对应关系 路由层

templates文件夹 里面放的全是html文件

# 服务端web框架文件

from wsgiref.simple_server import make_server
from urls import urls
from views import * def run(env,response):
"""
:param env: 请求相关的所有数据 将http数据全部提前处理成了字典的形式 供调用者使用
:param response: 响应相关的所有数据
:return: 给前端真正的数据
"""
# print(env)
response('200 OK',[('xxx','liu'),])
current_path = env.get('PATH_INFO')
# print(current_path)
# if current_path == '/index':
# return [b'index']
# elif current_path == '/login':
# return [b'login']
# 定义一个存储函数名的标志位
func = None
for url in urls: # url = ('/login',login) ('/index',index)
if current_path == url[0]: # 用户敲的后缀名 你后端有对应的处理业务
func = url[1] # 将匹配上的函数名赋值给func变量
break # 一旦用户匹配上了对应的业务接口 立刻结束匹配
# 判断func是否被赋值
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) # 实时监听本机8080端口
# 一旦有请求来了 会统一交给run函数处理(调用run函数并传参run(env,response))
server.serve_forever() # 启动服务端
<!--templates文件夹中的html文件-->
# xxx.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 rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<h1>我是xxx页面</h1>
</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 rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
sadadadasdsadsad
</body>
</html>
# 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 rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<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>
</body>
</html> # get_data.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 rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2 class="text-center">数据展示</h2>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>idd</th>
<th>name</th>
<th>sex</th>
<th>age</th>
<th>hire_date</th>
<th>post</th>
<th>post_comment</th>
<th>salary</th>
<th>office</th>
<th>depart_id</th>
</tr>
</thead>
<tbody>
{% for user_dic in user_list %}
<tr>
<td>{{ user_dic.idd }}</td>
<td>{{ user_dic.name }}</td>
<td>{{ user_dic.sex }}</td>
<td>{{ user_dic.age }}</td>
<td>{{ user_dic.hire_date}}</td>
<td>{{ user_dic.post }}</td>
<td>{{ user_dic.post_comment }}</td>
<td>{{ user_dic.salary }}</td>
<td>{{ user_dic.office }}</td>
<td>{{ user_dic.depart_id }}</td>
</tr>
{% endfor %}
</tbody> </table>
</div>
</div>
</div>
</body>
</html>
# view.py 文件

def login(env):
return 'login' def index(env):
return 'index' def reg(env):
return 'reg' def xxx(env):
# return 'xxx'
with open(r'G:\Python代码日常\day051 django\templates/xxl.html','r',encoding='utf-8') as f:
return f.read() def error(env):
return '404 error' import time
def get_time(env):
ctime = time.strftime('%Y-%m-%d %X')
# 后端数据 如何传递给html页面(利用字符串的替换)
with open(r'G:\Python代码日常\day051 django\templates/get_time.html','r',encoding='utf-8') as f:
data = f.read()
data = data.replace('sadadadasdsadsad',ctime)
return data from jinja2 import Template
def get_userdict(env):
user_dic = {'username':'jason','age':18,'hobby':['read','book','run']}
with open(r'G:\Python代码日常\day051 django\templates/get_user.html','r',encoding='utf-8') as f:
data = f.read()
temp = Template(data)
res = temp.render(userDic = user_dic) # 将user_dic传递给html页面 页面上通过userDic就能够拿到后端传递过来的值
return res import pymysql
def get_data(env):
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '123',
db = 'db3',
charset = 'utf8',
autocommit = True
)
cursor = conn.cursor(pymysql.cursors.DictCursor) # 将查出来的数据组织成一个字典
sql = "select * from userinfo" # 关键性的数据 不要自己手动拼接
affect_rows = cursor.execute(sql) # sql注入:就是利用MySQL注释语法
# print(affect_rows)
user_list = cursor.fetchall()
# print(user_list)
# return 'hahahahha'
with open(r'G:\Python代码日常\day051 django\templates/get_data.html','r',encoding='utf-8') as f:
data = f.read()
temp = Template(data)
res = temp.render(user_list = user_list)
return res
# urls.py

from views import *
urls = [
('/login',login),
('/index',index),
('/reg',reg),
('/xxx',xxx),
('/get_time',get_time),
('/get_userdict',get_userdict),
('/get_data',get_data),
]

动静态网页

静态网页

数据是写死的 万年不变(哪怕改变了 也是人为直接修改)

动态网页

数据是实时获取的

eg:

1 后端代码动态获取 当前时间

2 数据是从数据库查询出来的

	题目1
访问页面 页面上展示当前访问的时间 题目2
访问页面 页面上展示后端用户字典 并且在前端页面上可以
利用一些简便的方式操作字典取值 jinja2模板语法
专门用来处理后端数据与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 %}
基于jinja2模板语法 实现后端给html页面传值
模板语法是在后端生效的 浏览器是无法识别模板语法
所有的数据渲染全都是在后端事先生成好的 然后将完整的html页面丢给浏览器
{{ user_dic }}
{%for i in user_list%}
{%endfor%}
变量相关 {{}}
逻辑相关 {%%} {# #} 模板语法的注释,该语法注释之后,前端是看不到的,而原生的html的语法注释<!-- 电话费的-->前端可以看到,注意区别。

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都是自己写的

django框架介绍

注意事项

		*1.计算机名称不能有中文
2.python解释器不要使用3.7版本 推荐使用版本3.4~3.6,对Django兼容性比较好
3.一个pycharm窗口 只能跑一个项目,项目名不要有中文* django版本问题
django版本以1.11.11为主(1.11.9~1.11.13)

django下载方法

方式一:pycharm settings中安装

方式二:cmd安装

pip3 install django==1.11.11

如何检验django是否安装成功:
命令行敲 django-admin

django项目及app的创建

命令行创建项目

1.创建django项目

​ django-admin startproject 项目名(例如mysite)

2.启动django项目

​ 切换到项目文件夹下

​ python3 manage.py runserver

​ python3 manage.py runserver 127.0.0.1:8080

3.停止项目

ctrl+c

4.创建应用(django支持多app开发)

​ python3 manage.py startapp app01

注意:

1.命令行创建不会自动创建templates文件夹

2.配置文件中不会自动帮你书写templates文件路径

pycharm创建项目

​ 方法一:FILE>>>new project 选择第二个Django,命名项目名的时候名字不能为中文

​ 创建app,在Application中添加应用的名,直接创建项目及应用;可以不添加,后期手动创建应用。

方法二:打开菜单栏Tools>>>run manage task功能栏创建项目及应用

创建好的app需要在django配置文件中注册方可生效

强调:

1.用Django一定要保证只有一个在运行状态

2.调试Django项目的时候,一定记得清除浏览器的缓存(如果页面调试没有达到代码改的效果)

浏览器页面右键:检查》network》 Settings》Preferences》Network》Disable cache(while DevTools is open) 打上勾;

3.如果想想使用Django默认的端口可以自己修改,方法如下图:

app的概念

django是一个以开发app为主要功能的web框架

app就是application应用的意思

一个django项目就是一所大学(空的架子 本身没有任何功能),而app就类似于大学里面的各个学院;

一个空的django本身没有任何作用 仅仅是为app提高前期的环境配置

你可以根据功能的不同 开发多个app

一个app对应一个具体的功能模块

用户相关的功能 用户相关的app

订单相关的功能 订单相关的app

商品相关的功能 商品相关的app

每一个app都有自己独立的功能

Django主要文件介绍

应用文件夹(app)

​ migrations 数据库迁移记录相关数据

​ adnin.py django后台管理相关

​ models.py 模型表相关

​ views.py 视图函数相关

项目名

​ settings.py 配置文件

​ urls.py 路由与视图函数的映射关系

​ templates文件夹 项目用到的所有的html文件

​ manage.py django入口文件

Django基础必会的三个函数

​ from django.shortcuts import HttpResponse, render, redirect

HttpResponse

内部传入一个字符串参数,返回给浏览器。

# views.py
def index(request):
# 业务逻辑代码
return HttpResponse("你好,世界!")
# urls.py from firstapp import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index), # 添加对应的功能函数
]
# 启动服务端:Starting development server at http://127.0.0.1:9999/
# 在浏览器页面用 http://127.0.0.1:9999/index/连接服务端,将index函数内部字符串渲染到浏览器页面上。

render

除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。

将数据填充进模板文件,最后把结果返回给浏览器。(类似于我们上面用到的jinja2)

# views.py
def reg(request):
user_dic = {'username':'zhang','password':123}
# 下面两种方法都可以
return render(request,'reg.html',local()) # 拿到reg函数内部所有的局部变量,在html文件内部可以根据模板语法选择你要渲染到前端页面上的变量。
# return render(request,'reg.html',{'user_dic':user_dic})
# urls.py
from firstapp import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^reg/', views.reg),
]
# templates 文件夹建立 reg.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 rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head>
<body>
<form action="" class="form-control">
<label for="">username:<input type="text"></label>
<label for="">password<input type="text"></label>
<input type="submit" class="提交">
{{ user_dic }}
<div>{{user_dic.username }}</div>
<div>{{ user_dic.password }}</div> # 只支持点的方式,不支持字典的取值方式
</body>
</form>
</body>
</html>
# 启动服务端:Starting development server at http://127.0.0.1:9999/# 在浏览器页面用 http://127.0.0.1:9999/reg/连接服务端,将reg函数内部reg.html 文件渲染到浏览器页面上。

redirect(重定向)

接受一个URL参数,表示跳转到指定的URL(当前页面跳转)。

​ 1)可以写本网站的路径后缀;

​ 2)也可以写全路径,即:任意一个网页地址。

# views.py
def login(request):
# return redirect('http://www.baidu.com') # 访问login后缀名,重定向到百度网址
return redirect('/reg') # 本网站的后缀名 # urls.py
from firstapp import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^reg/', views.reg),
url(r'^login/', views.login),
]
# 启动服务端:Starting development server at http://127.0.0.1:9999/# 在浏览器页面用 http://127.0.0.1:9999/login/连接服务端,按照login函数内部redirect指定的网址跳转,或者路径=后缀。

注意:Django能自动识别到你对代码的修改,所以无需重启服务端,但是有时候识别比较缓慢,最好重新手动启动,也可以多刷新几次浏览器页面

下一篇:Django 之 文件配置、pycharm及django连接数据库、创表及表的增删改查02

Django框架简介(1)的更多相关文章

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

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

  2. Django框架简介及模板Template,filter

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

  3. Django框架简介与使用注意事项

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

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

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

  5. wsgiref模块、web框架、django框架简介

    """web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...

  6. 手动搭建简易web框架与django框架简介

    目录 纯手写简易web框架 基于wsgiref模块 动静态网页 简单了解jinja2模块 框架请求流程 python主流web框架 django框架 简介 应用app 命令操作django pycha ...

  7. Python学习笔记_04:Django框架简介

    目录 1 什么是Django? 2 Django框架的开发环境搭建 3 Django操作MySql数据库简介 4 功能强大的Django管理工具应用 1 什么是Django? Django是应用于We ...

  8. Django框架简介,wsgiref 与 jinja2 模块

    目录 框架简介 wsgiref模块 jinja2 模块 框架简介 Django是一个web开发框架,用来开发web应用,本质就是, web框架+socket服务端 MVC框架和MTV框架 MVC,全名 ...

  9. Django ---- 框架简介

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

  10. Django框架简介-开头

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

随机推荐

  1. Ubuntu下借助URLOS实现快速安装DzzOffice企业办公套件

    如今,越来越多的个人.团队甚至企业都在使用GSuite或者Office365等网络办公套件,为什么人们越来越喜爱使用网络办公套件?一方面是考虑数字资产的安全性以及管理效率,另一方面则是日益增大的协同办 ...

  2. Java架构师 -- 知识库

    1,CSDN知识库: http://lib.csdn.net/base/architecture 2,淘宝

  3. 论文阅读 | Generating Fluent Adversarial Examples for Natural Languages

    Generating Fluent Adversarial Examples for Natural Languages   ACL 2019 为自然语言生成流畅的对抗样本 摘要 有效地构建自然语言处 ...

  4. 学习shell的第三天

    编程原理:1.编程介绍 早期编程:  驱动 硬件默认是不能使用的:   不同的厂家硬件设备之间需要进行指令沟通,我们需要驱动程序来进行“翻译”:  更趋近与硬件开发的工程师,要学习“汇编语言”:而“汇 ...

  5. JS中正则表达式应用

    判断字符串是否含有中文字符: var pattern = /.*[\u4e00-\u9fa5]+.*$/; var str = "asd按时"; console.log(patte ...

  6. [Codeforces 266E]More Queries to Array...(线段树+二项式定理)

    [Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...

  7. Python 入门 之 包

    Python 入门 之 包 1.包 (1)什么是包? 文件夹下具有_ init.py _的文件夹就是一个包 (2)包的作用: 管理模块(文件化) (3)包的导入: 导入: 启动文件要和包文件是同级 绝 ...

  8. Codeforces 1201C. Maximum Median

    传送门 看到中位数考虑先把数排序一下 然后有个显然的贪心,一个数增加后一定不能比下一个数大,不然我们直接增加下一个数显然更优 所以初始时的中位数操作后也是中位数 那么我们只要考虑中间再往后怎么加使得答 ...

  9. html2canvas+Canvas2Image分享海报功能踩坑

    首先需要 import html2canvas from 'html2canvas'; import {Canvas2Image} from '../../assets/js/plug/canvas2 ...

  10. 欧拉系统-登陆 SSH 出现 Access Denied 错误

    1./home 权限问题如果 /home 只支持 root 访问,那么不妨试一下 /tmp ,然后用 mv 命令再转移 2./etc/ssh/sshd_config 配置问题     vi  /etc ...