day49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目
目录
自定义web框架wsgiref版
1.wsgiref构建服务端
wsgiref本身就是个web框架,提供了一些固定的功能(请求和响应信息的封装),
有了wsgiref我们就不需要自己写原生的socket了
也不需要咱们自己来完成请求信息的提取了
整体结构和socketserver类似
2.登录函数逻辑
登录操作 进入页面为get请求 提交数据是post请求
def login(environ):
# 回复login.html
# environ['QUERY_STRING'] --'username=chao'
method = environ['REQUEST_METHOD']
if method == 'GET': # 打开login页面
with open('login.html', 'rb') as f:
data = f.read()
return data
else:
print(environ)
content_length = int(environ.get('CONTENT_LENGTH',0)) # 获取'username=asdf&password=asdf的长度 # environ['wsgi.input']是post对象,对象中内置了read方法,参数是长度,读出来的是字节流,再decode一下,得到字符串
data = environ['wsgi.input'].read(content_length).decode('utf-8') # environ['wsgi.input']是post对象 #post请求提交过来的数据
print('请求数据为', data) #请求数据为 b'username=asdf&password=asdf # 使用parse_qs的原因:'username=asdf&password=asdf这个字符串把用户名和密码完全切割出来太麻烦
# parse_qs可以将这个字符串格式化成我们需要的字典,这样的话取值非常方便
data = parse_qs(data)
print('格式化之后的数据',data) #格式化之后的数据 {'username': ['chao'], 'password': ['123']} # 通过字典轻而易举获取post提交过来的用户名和密码
uname = data.get('username')
pwd = data.get('password') # 调用check函数 检测用户名密码是否正确,返回一个是否成功状态status
status = check(uname,pwd)
# 登录成功 跳转到html页面
if status:
data = html(environ)
return data
# 登录失败 给一个错误提示
else:
return b'gunduzi'
3.application函数逻辑(替代socket)
def application(environ, start_response):
'''
:param environ: 是全部加工好的请求信息,加工成了一个字典,通过字典取值的方式就能拿到很多你想要拿到的信息
:param start_response: 帮你封装响应信息的(响应行和响应头),注意下面的参数
:return:
'''
path = environ['PATH_INFO']
print(environ)
'''
urlpatterns = [
('/', html),
('/login', login),
('/vip.html', vip),
('/spa.ico', ico),
('/test.css', css),
('/test.js', js),
('/2.jpg', jpg), ]
'''
for url in urlpatterns:
if url[0] == path:
data = url[1](environ)
break
else:
return b'404 page not found' # 封装响应行和响应头的
start_response('200 OK', [('a','1'),]) # print(environ)
# print(environ['PATH_INFO']) #输入地址127.0.0.1:8000,这个打印的是'/',输入的是127.0.0.1:8000/index,打印结果是'/index'
return [data] httpd = make_server('127.0.0.1', 8001, application)
'''
make_server的作用:
将请求信息处理成一个字典
把 [data] 响应到html页面
''' print('Serving HTTP on port 8001...')
# 开始监听HTTP请求:
httpd.serve_forever()
4.创建数据库并插入数据
如果我们要做一个登陆注册的一个界面,肯定要输入用户名和密码,这时候肯定要涉及数据库的操作了
so 我们在数据库中创建一些数据
mysql> create database db1;
Query OK, 1 row affected (0.00 sec) mysql> use db1;
Database changed
mysql> create table userinfo(id int primary key auto_increment,username char(20) not null unique,password char(20) not null);
Query OK, 0 rows affected (0.23 sec) mysql> insert into userinfo(username,password) values('chao','666'),('sb1','222');
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from userinfo;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 1 | chao | 666 |
| 2 | sb1 | 222 |
+----+----------+----------+
2 rows in set (0.00 sec)
5.pymysql连接数据库对数据库进行操作
数据创建好了,我们现在想要用python对数据库进行操作,所以需要pymysql来连接一下
#创建表,插入数据
def createtable():
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='666',
database='db1',
charset='utf8'
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
sql = '''
-- 创建表
create table userinfo(id int primary key auto_increment,username char(20) not null unique,password char(20) not null);
-- 插入数据
insert into userinfo(username,password) values('chao','666'),('sb1','222');
'''
cursor.execute(sql)
conn.commit()
cursor.close()
conn.close()
6.auth登录验证
现在有数据库了,我们就可以对用户名和密码进行验证了
在auth函数中传入用户输入的用户名和密码,通过select查询结果确定用户名和面是否正确
#对用户名和密码进行验证
def auth(username,password):
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123',
database='db1',
charset='utf8'
)
print('userinfo',username,password)
cursor = conn.cursor(pymysql.cursors.DictCursor)
sql = 'select * from userinfo where username=%s and password=%s;'
res = cursor.execute(sql, [username, password])
if res:
return True
else:
return False
7.登录页面-login.html
在网页上,我们要看到一个用户名和密码的输入框,所以需要创建一个前端html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--如果form表单里面的action什么值也没给,默认是往当前页面的url上提交你的数据,所以我们可以自己指定数据的提交路径-->
<!--<form action="http://127.0.0.1:8080/auth/" method="post">-->
<form action="http://127.0.0.1:8080/auth/" method="get">
用户名<input type="text" name="username">
密码 <input type="password" name="password">
<input type="submit">
</form> <script> </script>
</body>
</html>
8.登陆成功的跳转界面
登录成功后,有一个跳转页面,所以需要创建一个跳转页面的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
h1{
color:red;
}
</style>
</head>
<body>
<h1>宝贝儿,恭喜你登陆成功啦</h1> </body>
</html>
自定义web框架wsgiref版-优化版
优化版和上面的版本有什么不同?
对之前的版本进行优化,将不同的函数按照功能分别写到不同的文件和文件夹中
下面是文件的一个结构图:

关于上图的解释
1.static用于存放一些静态文件
包括css js icon jpg图片这种文件
2.template存放前端html文件
3.auth用来存放一些需要验证的函数
import pymysql def check(username, pwd):
conn = pymysql.connect(
host='152.136.114.188',
port=3306,
user='root',
password='123456',
database='django',
charset='utf8'
)
cursor = conn.cursor()
sql = 'select * from userinfo where username=%s and password=%s;'
res = cursor.execute(sql, [username, pwd])
if res:
return True
else:
return False
4.manage.py是用来实现执行命令的函数
这样我们在pycharm命令行中通过 python manage.py xxx就可以执行相关命令了
from models import UserInfo
from wsgi import run import sys
args = sys.argv
print(args) #['manage.py', 'migrate']
print(args[1])
if args[1] == 'migrate':
obj = UserInfo()
obj.create_model()
elif args[1] == 'runserver':
ip = args[2]
port = int(args[3])
print(ip,port)
# print(type(port))
run(ip, port) # python manage.py runserver 127.0.0.1 8001
5.models.py是和数据库相关的
主要完成了用python连接mysql的相关配置信息以及python对mysql进行一些增删改查操作用的
class UserInfo:
def create_model(self):
import pymysql
conn = pymysql.connect(
host='152.136.114.188',
port=3306,
user='root',
password='123456',
database='django',
charset='utf8'
)
cursor = conn.cursor()
sql = '''
create table userinfo(id int primary key auto_increment, username char(10), password char(10));
'''
cursor.execute(sql)
conn.commit()
6.urls.py是用来确定url路径的,并且通过访问相应的路径,可以执行和路径相关的函数(view)
import views
urlpatterns = [ ('/home', views.home),
('/login', views.login),
('/vip.html', views.vip),
('/favicon.ico', views.ico),
('/test.css', views.css),
('/test.js', views.js),
('/2.jpg', views.jpg), ]
7.views.py是用来实现主要逻辑的,和项目内容逻辑相关的函数都写在这里面
def home(environ):
msg = {'name': 'chao', 'hobby': ['女人', 'ddj', '小电影']}
# with open('./templates/index.html', 'rb') as f:
# data = f.read()
with open('./templates/index.html', 'r', encoding='utf-8') as f:
data = f.read()
t = Template(data)
ret = t.render(msg)
return ret.encode('utf-8')
8.wsgi.py是web框架的服务器, 它代替了socket
from urls import urlpatterns
from wsgiref.simple_server import make_server def run(ip, port):
# print('xxxxxxxx')
def application(environ, start_response):
'''
:param environ: 是全部加工好的请求信息,加工成了一个字典,通过字典取值的方式就能拿到很多你想要拿到的信息
:param start_response: 帮你封装响应信息的(响应行和响应头),注意下面的参数
:return:
'''
path = environ['PATH_INFO'] for url in urlpatterns:
if url[0] == path:
data = url[1](environ)
break
else:
data = b'404 page not found' start_response('200 OK', [('a', '1'), ]) return [data] httpd = make_server(ip, port, application) # print('Serving HTTP on port 8001...')
# 开始监听HTTP请求:
httpd.serve_forever()
模板渲染JinJa2
如果我们想实现一个动态页面
之前使用的方法是:
假设以时间为例,在前端页面上显示时间戳(刷新就会显示当前时间戳)
怎么做到这件事呢?
def html(environ):
# 1.创建一个当前时间时间戳
current_time = str(time.time()) # 2.读出当前的html文件
with open('./templates/home.html', 'r', encoding='utf-8') as f:
data = f.read()
# 3.将文件中的xxoo替换为时间戳
data = data.replace('xxoo', current_time).encode('utf-8')
return data
在home.html中,搞一个字符串xxoo,然后时间戳就能够替换上去了
<body>
<!-- 在html文件中,写一个标签,其中的内容有xxoo -->
<h1>皇家赌场--xxoo</h1>
<a href="http://127.0.0.1:8002/vip.html">会员中心</a>
<img src="2.jpg" alt="">
<div class="c1" id="d1"></div>
</body>
其实,这种行为从专业角度老说,叫做模板渲染
这个过程其实就是HTML模板渲染数据
本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。
我这里用的特殊符号是我定义的
其实模板渲染有个现成的工具:JinJa2
用JinJa2实现动态界面
from jinja2 import Template def index():
with open("index2.html", "r",encoding='utf-8') as f:
data = f.read()
template = Template(data) # 生成模板文件
ret = template.render({"name": "于谦", "hobby_list": ["烫头", "泡吧"]}) # 把数据填充到模板里面
return [bytes(ret, encoding="utf8"), ]
在JinJa2中 特殊符号就是{{ }} or {% %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>姓名:{{name}}</h1>
<h1>爱好:</h1>
<ul>
{% for hobby in hobby_list %}
<li>{{hobby}}</li>
{% endfor %}
</ul>
</body>
</html>
上面.py中的数据是我们手动写的
当然我们也可以从数据库中获取数据,但是前提一定要配置用pymysql配置好数据库哦
MTV和MVC框架
MVC框架
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:

MTV框架
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是指:
- M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
- T 代表模板 (Template):负责如何把页面展示给用户(html)。
- V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:

一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
django:下载安装&创建启动
1.下载django
pip3 install django==1.11.9
2.创建一个django的project
django-admin startproject mysite # 创建了一个名为"mysite"的Django 项目:
当我们执行完这条指令后 ,会出现如下一堆文件

这些文件的作用:
- manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件。
- settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
- urls.py ----- 负责把URL模式映射到应用程序。
- wsgi.py ---- runserver命令就使用wsgiref模块做简单的web server,后面会看到renserver命令,所有与socket相关的内容都在这个文件里面了,目前不需要关注它。
3.创建django APP应用
刚才我们只是创建了一个django项目,但是里面并没有之前所提到的models.py views.py这些文件
这是因为我们只是创建了django项目,并没有创建一个django的app
所以这个app需要我们执行一条指令去创建
python manage.py startapp blog2 #创建一个django应用 每个应用的目录下都有自己的views.py视图函数和models.py数据库操作相关的文件
当我们执行完这条指令后,会发现文件夹多了几个文件

我们现在只需要看其中两个文件
models.py :之前我们写的那个名为model的文件就是创建表用的,这个文件就是存放与该app(应用)相关的表结构的
views.py :存放与该app相关的视图函数的
其他的先不用管,以后会知道的
4.启动django项目
python manage.py runserver 8080 # python manage.py runserver 127.0.0.1:8080,本机就不用写ip地址了 如果连端口都没写,默认是本机的8000端口
这样我们的django就启动起来了。当我们访问:http://127.0.0.1:8080/时就可以看到:

这是django里自己写的一个html文件,当看到这个页面就说明,我们的django启动成功了
day49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目的更多相关文章
- dya49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目
目录 1.自定义web框架wsgiref版 2.自定义web框架wsgiref版-优化版 3.模板渲染JinJa2 4.MTV和MVC框架 5.django:下载安装&创建启动 自定义web框 ...
- Web框架本质及第一个Django实例 Web框架
Web框架本质及第一个Django实例 Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web ...
- day51:django:dispatch&模板渲染&过滤器&标签&组件&静态文件配置
目录 1.dispatch 2.模板渲染 3.过滤器 4.标签 5.组件 6.静态文件配置 dispatch 回顾:CBV对应的URL传参 urls.py url(r'^book/(\d+)/(\d+ ...
- Web框架本质及第一个Django实例
Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...
- Django之Web框架本质及第一个Django实例
Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...
- DAY15-web框架本质及第一个Django实例
Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...
- 创建第一个Django项目
第一个Django项目 命令行下使用如下命令创建一个名为"mysite"的Django项目: django-admin startproject mysite 这将会在当前位置创建 ...
- django学习笔记【002】创建第一个django app
2.3.3 1.创建一个名叫polls的app python3. manage.py startapp polls tree mysite/ mysite/ ├── db.sqlite3 ├── ma ...
- 创建第一个django工程
一.环境搭建 使用anaconda + pycharm的环境. 1.创建虚拟环境并安装django1.8的包 # 创建虚拟环境 conda create -n django python=3.6 # ...
- Django学习(七) 创建第一个Django项目
如果这是你第一次使用Django,你必须进行一些初始设置.即,您将需要自动生成一些代码,建立了Django项目. 从命令行.cd进入一个目录,你想要存储您的代码,然后运行以下命令: django-ad ...
随机推荐
- Java 实现汉字按照首字母分组排序
一.实现思路: 1.将数据list 进行排序Collections,排序后是按照汉字字母排序的 2.循环找出26个字母,以字母为key,以list中相同首字母的数据为值(集合) 二.代码实现: // ...
- 2vue
事件 v-on:click="handle" @click="handle" handle创建在methods里 <!DOCTYPE html> & ...
- 【再学WPF】自定义样式
1.添加"资源字典": 工程名称:WpfApp1 新建Styles文件夹:创建"Dictionary1.xaml"的文件: 2.编辑样式: <SolidC ...
- 双调排序--GPU/AIPU适合的排序【转载】
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入 双调排序是data-indepen ...
- Typora配置本地图片自动上传阿里云OSS
一.下载Typora Gitee下载地址 二.下载Picgo.app Github下载地址 三.配置Picgo 打开Typora,格式→图像→图像全局设置: 四.图床设置 注册阿里云账号 打开 ...
- Executors.newScheduledThreadPool()定时任务线程池
定时任务线程池是由 Timer 进化而来 jdk中的计划任务 Timer 工具类提供了以计时器或计划任务的功能来实现按指定时间或时间间隔执行任务,但由于 Timer 工具类并不是以池 pool ,而是 ...
- Linux基础——操作系统
1. 操作系统(Operation System,OS) 操作系统作为接口的示意图 如果想在裸机上运行自己所编写的程序,就必须用机器语言书写程序如果计算机上安装了操作系统,就可以在操作系统上安装支持的 ...
- 学习记录--C++继承与派生编程题
1.设计一个圆类circle和一个桌子类table,另设计一个圆桌类roundtable,它是从前两个类派生出来的 要求输出一个圆桌的高度,面积与颜色等. #include<iostream&g ...
- 远程云服务器上docker安装redis的过程
首先明确一点,云服务环境你已经安装好了docker 1.进入docker hub官网查看你所需要的redis的版本信息 https://registry.hub.docker.com/
- 关于 Android sdk manager 的安装问题
最近刚刚接触小程序测试,故此需要搭建环境 我用的是python3.6+appium1.8.2+Android sdk manager 关于应用程序,大家有需要的话,可以找我要. 1.关于安装Andro ...