Django 系列博客(一)

前言

学习了 python 这么久,终于到了Django 框架。这可以说是 python 名气最大的web 框架了,那么从今天开始会开始从 Django框架的安装到使用一步步的学习,这系列博客不会像前端的那样水了(立个 flag),希望可以成为高质量的博客。那么本篇博客介绍 Django 的安装以及如何在电脑上运行第一个 Django 应用。

Django 的安装

Django 的安装很简单,在 win 和 mac 上面都可以使用 pip 安装命令安装,也可以通过 pycharm 安装,或者下载文件在命令行使用安装工具安装。

接下来我在 ubuntu 上安装做示例。

在这里还安装了一个依赖包 pytz。这是用来做时区转换的一个第三方库。

其他平台的 pip 安装方式一样,不过要选用 python3的对应 pip 来安装,因为现在的 Django 版本已经不支持 python2了。

虚拟环境的安装

什么是虚拟环境

  • 对真实的 python 解释器的一个拷贝版本
  • 事实有效,可以独立存在并运行解释 python 代码
  • 可以在计算机上拷贝多个虚拟环境

为什么要使用虚拟环境

  • 保证真实环境的纯净性
  • 框架的多版本共存
  • 方便做框架的版本迭代
  • 降低多框架共存的维护成本

安装虚拟环境

  1. 通过 pip 安装虚拟环境库

因为我之前已经下载好了,所以这里直接显示请求已经完成,并且后面是安装的绝对路径。

  1. 前往目标文件夹

这个文件夹是你用来保存虚拟环境的文件夹,该文件夹一旦确定就不要轻易更改。

这个 py3-env1是创建的一个纯净虚拟环境。

  1. 创建纯净的虚拟环境
virtualenv 虚拟环境名 (py3-env2)
  1. 终端启动虚拟环境
cd py3-env1\Scripts
activate
  1. 进入虚拟环境下的 python 开发环境
python3
  1. 关闭虚拟环境
deactivate
  1. Pycharm的开发配置
添加:创建项目 -> Project Interpreter -> Existing interpreter -> Virtualenv Environment | System Interpreter -> 目标路径下的 python.exe
删除:Setting -> Project -> Project Interpreter -> Show All

mac 电脑从第三步直接到最后一步就好

了解

# 创建非纯净环境:
# -- virtualenv-clone 本地环境 虚拟环境名
# Mac配置终端,在终端运行虚拟环境
# 在用户根目录下的.bash_profile(没有需手动创建)文件中设置
# alias 终端指令名(env-py3)='/Library/Virtualenv/虚拟环境名/bin/python3'
# alias 终端指令名(env-pip3)='/Library/Virtualenv/虚拟环境名/bin/pip3'

HTTP 协议

因为 Django 框架应用层是采用的 HTTP 协议,所以有必要了解 HTTP 协议。

什么是 HTTP 协议

  • HTTP(HyperText Transport Protocol) 是超文本传输协议,而 HTTPS 也归属于 HTTP 协议,S 代表安全。
  • 基于 TCP/IP协议基础上的应用层协议,底层实现仍为 socket
  • 基于请求-响应模式:通信一定是从客户端开始,服务端接收到客户端一定会做出对应响应
  • 无状态:协议不对任何一次通信状态和任何数据做保存
  • 无连接:一次连接只完成一次请求-响应,请求-响应完毕后会立即断开连接。

HTTP 工作原理

一次 HTTP 连接称之为一个事务,过程可以分为四步

  1. 客户端与服务端建立连接
  2. 客户端发生一个 HTTP 协议指定格式的请求
  3. 服务端接收请求后,回应一个 HTTP 协议指定格式的响应
  4. 客户端将服务端的响应展现给用户

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
'''

使用原生 socket 完成和浏览器的交互

目录结构

01_socket
-- 01_client.html:前台通过form表单访问后台的页面
-- 01_login.html:后台测试渲染给前台的登录页面
-- 01_index.html:后台测试渲染给前台的主页
-- 01_server.py:后台服务器文件

因为 B/S架构的客户端已经由浏览器写好,所以只需要关注服务器端就ok。

服务器端代码

from socket import socket

# 设置响应头(包含响应行)
RESP_HEADER = b'HTTP/1.1 200 OK\r\nContent-type:text/html;charset=utf-8\r\n\r\n' # 连续两个\r\n表示响应头结束 # 设置服务器 socket 相关信息
server = socket()
server.bind('', 8080) # 空字符串表示绑定本机
server.listen(5)
print(('服务:http://localhost:8080')) while True:
# 获取以 http 协议发来的请求
client, addr = server.accept()
data = client.recv(1024)
# 数据报文 包含请求行 请求头 请求体
print(data)
client.send(RESP_HEADER) # /index => 响应主页
# /login => 登录页面
# 错误 => 404
# 数据 data, 字节形式 => 字符串形式
strData = str(data, encodeing) # 解析请求的数据,分析得到路由
my_route = strData.split('\r\n')[0].split(' ')[1] # 后台没有设置的路由,统统由404来处理
dt = b'404' # 设置的路由返回响应的页面文件
if my_route == '/index':
with open('index 页面路径', 'rb') as f:
dt = f.read()
if my_route == '/login':
with open('login 页面路径', 'rb') as f:
dt = f.read() # /favicon.ico该请求是往后台请求标签图标
if my_route == '/favicon.ico':
with open('favicon.ico', 'rb') as f:
dt = f.read()
# 服务器发送响应体
client.send(dt)
# 一次循环,代表一次响应,也就是一次事务的完成,要关闭 http 请求连接
client.close()

修改返回数据,完善响应体

# 字符串
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('01_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('01_index.html', 'rb') as f:
dt = f.read()
elif route == '/login':
with open('01_login.html', 'rb') as f:
dt = f.read()
else:
dt = b'404'
client.send(dt)

框架演变

目录结构

02_frame
-- 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.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)
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.ico': 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 系列博客(一)的更多相关文章

  1. Django 系列博客(十六)

    Django 系列博客(十六) 前言 本篇博客介绍 Django 的 forms 组件. 基本属性介绍 创建 forms 类时,主要涉及到字段和插件,字段用于对用户请求数据的验证,插件用于自动生成 h ...

  2. Django 系列博客(十四)

    Django 系列博客(十四) 前言 本篇博客介绍在 html 中使用 ajax 与后台进行数据交互. 什么是 ajax ajax(Asynchronous Javascript And XML)翻译 ...

  3. Django 系列博客(十三)

    Django 系列博客(十三) 前言 本篇博客介绍 Django 中的常用字段和参数. ORM 字段 AutoField int 自增列,必须填入参数 primary_key=True.当 model ...

  4. Django 系列博客(十二)

    Django 系列博客(十二) 前言 本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询. 聚合查询 语法:aggregate(*args, **kwargs) ...

  5. Django 系列博客(十一)

    Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...

  6. Django 系列博客(十)

    Django 系列博客(十) 前言 本篇博客介绍在 Django 中如何对数据库进行增删查改,主要为对单表进行操作. ORM简介 查询数据层次图解:如果操作 mysql,ORM 是在 pymysql ...

  7. Django 系列博客(九)

    Django 系列博客(九) 前言 本篇博客介绍 Django 模板的导入与继承以及导入导入静态文件的几种方式. 模板导入 模板导入 语法:``{% include '模板名称' %} 如下: < ...

  8. Django 系列博客(八)

    Django 系列博客(八) 前言 本篇博客介绍 Django 中的模板层,模板都是Django 使用相关函数渲染后传输给前端在显式的,为了想要渲染出我们想要的数据,需要学习模板语法,相关过滤器.标签 ...

  9. Django 系列博客(七)

    Django 系列博客(七) 前言 本篇博客介绍 Django 中的视图层中的相关参数,HttpRequest 对象.HttpResponse 对象.JsonResponse,以及视图层的两种响应方式 ...

  10. Django 系列博客(六)

    Django 系列博客(六) 前言 本篇博客介绍 Django 中的路由控制部分,一个网络请求首先到达的就是路由这部分,经过路由与视图层的映射关系再执行相应的代码逻辑并将结果返回给客户端. Djang ...

随机推荐

  1. LinkeList 特有方法

    LinkedList:特有方法:addFirst();addLast();添加元素到集合,添加到头尾,getFirst();getLast();获取元素,但不删除元素.如果集合中没有元素,会出现NoS ...

  2. centos 安装部署zabbix

    Zabbix_server初始安装部署 各模块要安装的模块 Server:server+nginx+mysql+php Agentd:agentd Proxy:proxy+mysql 1.准备环境: ...

  3. CentOS7 安装配置rsync

    centos7自带rsync,今天简单记录下. rsync安装配置步骤 服务器端: 1.修改默认配置文件/etc/rsyncd.conf,该成如下: # /etc/rsyncd: configurat ...

  4. python property对象

    一.从@porperty说起 Python内置的@property装饰器是负责把一个方法变成属性调用的 class Stu(object): def __init__(self,age): self. ...

  5. 2019/3/1 IO流的学习总结

    Java学习之IO流 学习Io流之前,我们先了解文件,以及在Java中对文件的操作.首先对文件进行操作,就必须用 File F = new File(“d:\\文件名”); 表示该文件或文件夹的地址寻 ...

  6. IDEA安装插件提示was not installed: Cannot download解决办法

    打开settings->system settings->updata,把下面的Use secure Connetion去掉

  7. github使用步骤

    首先需要注册一个github账号 1.认识github首页界面 2.如何新建一个自己的仓库 3.创建README文件 4.创建自己的文件 5.解析文件 6.生成地址 7.如何修改编辑文件

  8. program--历史故事

  9. Qt Creator快捷键设置

    QT Creator 下载地址 http://download.qt.io/ 一.快捷键配置方法: 进入“工具->选项->环境->键盘”即可配置快捷键. 二.常用默认快捷键:   编 ...

  10. 2017年7月最新浏览器市场份额,IE8份额仅剩个位数

    数据来源为百度统计所覆盖的超过150万的站点,样本为2017年6月1日-2017年6月30日最新一个月的数据. 统计如下: 其中IE8的份额为9.83%,首次降至个位数.在所有IE版本中,份额最高的是 ...