Django了解及安装

Web框架

想象一下,之前我们都有学习过网络编程相关的知识,应该可以理解,所有的web应用从本质都可以说是一个socket服务端,而用户使用的浏览器就是socket客户端

自定义web框架

1import socket 2 3server = socket.socket() 4server.bind(("127.0.0.1", 80)) 5server.listen() 6 7while True: 8 conn, addr = server.accept() 9 data = conn.recv(8096) 10 conn.send(b"OK") 11 conn.close()

可能当你看到这几行简单的代码感觉,这不就是一个简单的服务端,虽然看上去简单,但是可以说是web框架的本质就是从这几行代码当中扩展出去的

用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定? 你这个网站是这个规定,他那个网站按照他那个规定,这互联网还能玩么?

所以,必须有一个统一的规则,让大家发送消息、接收消息的时候有个格式依据,不能随便写。

这个规则就是HTTP协议,以后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。

HTTP协议

如果再正常的工作当中使用上面那几行简单的socket肯定是不可以的,所以我们将它稍微的扩展延伸一下

1import socket 2sk = socket.socket() 3sk.bind(("127.0.0.1", 8080)) # 绑定IP和端口 4sk.listen() # 监听 5 6 7# 将返回不同的内容部分封装成函数 8def index(url): 9 s = "这是{}页面!".format(url) 10 return bytes(s, encoding="utf8") 11 12 13def home(url): 14 s = "这是{}页面!".format(url) 15 return bytes(s, encoding="utf8") 16 17 18# 定义一个url和实际要执行的函数的对应关系 19list1 = [ 20 ("/index/", index), 21 ("/home/", home), 22] 23 24while 1: 25 # 等待连接 26 conn, add = sk.accept() 27 data = conn.recv(8096) # 接收客户端发来的消息 28 # 从data中取到路径 29 data = str(data, encoding="utf8") # 把收到的字节类型的数据转换成字符串 30 # 按\r\n分割 31 data1 = data.split("\r\n")[0] 32 url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 33 conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因为要遵循HTTP协议,所以回复的消息也要加状态行 34 # 根据不同的路径返回不同内容 35 func = None # 定义一个保存将要执行的函数名的变量 36 for i in list1: 37 if i[0] == url: 38 func = i[1] 39 break 40 if func: 41 response = func(url) 42 else: 43 response = b"404 not found!" 44 45 # 返回具体的响应消息 46 conn.send(response) 47 conn.close()

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

返回具体的HTML文件

1import socket 2sk = socket.socket() 3sk.bind(("127.0.0.1", 8080)) # 绑定IP和端口 4sk.listen() # 监听 5 6 7# 将返回不同的内容部分封装成函数 8def index(url): 9 # 读取index.html页面的内容 10 with open("index.html", "r", encoding="utf8") as f: 11 s = f.read() 12 # 返回字节数据 13 return bytes(s, encoding="utf8") 14 15 16def home(url): 17 with open("home.html", "r", encoding="utf8") as f: 18 s = f.read() 19 return bytes(s, encoding="utf8") 20 21 22# 定义一个url和实际要执行的函数的对应关系 23list1 = [ 24 ("/index/", index), 25 ("/home/", home), 26] 27 28while 1: 29 # 等待连接 30 conn, add = sk.accept() 31 data = conn.recv(8096) # 接收客户端发来的消息 32 # 从data中取到路径 33 data = str(data, encoding="utf8") # 把收到的字节类型的数据转换成字符串 34 # 按\r\n分割 35 data1 = data.split("\r\n")[0] 36 url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 37 conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因为要遵循HTTP协议,所以回复的消息也要加状态行 38 # 根据不同的路径返回不同内容 39 func = None # 定义一个保存将要执行的函数名的变量 40 for i in list1: 41 if i[0] == url: 42 func = i[1] 43 break 44 if func: 45 response = func(url) 46 else: 47 response = b"404 not found!" 48 49 # 返回具体的响应消息 50 conn.send(response) 51 conn.close()

返回具体的HTML文件

将其变成动态网页

1import socket 2import time 3 4sk = socket.socket() 5sk.bind(("127.0.0.1", 8080)) # 绑定IP和端口 6sk.listen() # 监听 7 8 9# 将返回不同的内容部分封装成函数 10def index(url): 11 with open("index.html", "r", encoding="utf8") as f: 12 s = f.read() 13 now = str(time.time()) 14 s = s.replace("@@oo@@", now) # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号 15 return bytes(s, encoding="utf8") 16 17 18def home(url): 19 with open("home.html", "r", encoding="utf8") as f: 20 s = f.read() 21 return bytes(s, encoding="utf8") 22 23 24# 定义一个url和实际要执行的函数的对应关系 25list1 = [ 26 ("/index/", index), 27 ("/home/", home), 28] 29 30while 1: 31 # 等待连接 32 conn, add = sk.accept() 33 data = conn.recv(8096) # 接收客户端发来的消息 34 # 从data中取到路径 35 data = str(data, encoding="utf8") # 把收到的字节类型的数据转换成字符串 36 # 按\r\n分割 37 data1 = data.split("\r\n")[0] 38 url = data1.split()[1] # url是我们从浏览器发过来的消息中分离出的访问路径 39 conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 因为要遵循HTTP协议,所以回复的消息也要加状态行 40 # 根据不同的路径返回不同内容 41 func = None # 定义一个保存将要执行的函数名的变量 42 for i in list1: 43 if i[0] == url: 44 func = i[1] 45 break 46 if func: 47 response = func(url) 48 else: 49 response = b"404 not found!" 50 51 # 返回具体的响应消息 52 conn.send(response) 53 conn.close()

让网页动态起来

服务器程序和应用程序

对于真实开发中的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开发环境用的就是这个模块来做服务器。

wsgiref

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

1""" 2根据URL中不同的路径返回不同的内容--函数进阶版 3返回HTML页面 4让网页动态起来 5wsgiref模块版 6""" 7 8import time 9from wsgiref.simple_server import make_server 10 11 12# 将返回不同的内容部分封装成函数 13def index(url): 14 with open("index.html", "r", encoding="utf8") as f: 15 s = f.read() 16 now = str(time.time()) 17 s = s.replace("@@oo@@", now) 18 return bytes(s, encoding="utf8") 19 20 21def home(url): 22 with open("home.html", "r", encoding="utf8") as f: 23 s = f.read() 24 return bytes(s, encoding="utf8") 25 26 27# 定义一个url和实际要执行的函数的对应关系 28list1 = [ 29 ("/index/", index), 30 ("/home/", home), 31] 32 33 34def run_server(environ, start_response): 35 start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 36 url = environ['PATH_INFO'] # 取到用户输入的url 37 func = None 38 for i in list1: 39 if i[0] == url: 40 func = i[1] 41 break 42 if func: 43 response = func(url) 44 else: 45 response = b"404 not found!" 46 return [response, ] 47 48 49if __name__ == '__main__': 50 httpd = make_server('127.0.0.1', 8090, run_server) 51 print("我在8090等你哦...") 52 httpd.serve_forever()

View Code

jinja2

上面的代码实现了一个简单的动态,我完全可以从数据库中查询数据,然后去替换我html中的对应内容,然后再发送给浏览器完成渲染。 这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具: jinja2

下载jinja2:

pip install jinja2

1<!DOCTYPE html> 2<html lang="zh-CN"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="x-ua-compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>Title</title> 8</head> 9<body> 10 <h1>姓名:{{name}}</h1> 11 <h1>爱好:</h1> 12 <ul> 13 {% for hobby in hobby_list %} 14 <li>{{hobby}}</li> 15 {% endfor %} 16 </ul> 17</body> 18</html>

html文件

使用jinja2渲染html文件:

1from wsgiref.simple_server import make_server 2from jinja2 import Template 3 4 5def index(): 6 with open("index.html", "r") as f: 7 data = f.read() 8 template = Template(data) # 生成模板文件 9 ret = template.render({"name": "Alex", "hobby_list": ["烫头", "泡吧"]}) # 把数据填充到模板里面 10 return [bytes(ret, encoding="utf8"), ] 11 12 13def home(): 14 with open("home.html", "rb") as f: 15 data = f.read() 16 return [data, ] 17 18 19# 定义一个url和函数的对应关系 20URL_LIST = [ 21 ("/index/", index), 22 ("/home/", home), 23] 24 25 26def run_server(environ, start_response): 27 start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 28 url = environ['PATH_INFO'] # 取到用户输入的url 29 func = None # 将要执行的函数 30 for i in URL_LIST: 31 if i[0] == url: 32 func = i[1] # 去之前定义好的url列表里找url应该执行的函数 33 break 34 if func: # 如果能找到要执行的函数 35 return func() # 返回函数的执行结果 36 else: 37 return [bytes("404没有该页面", encoding="utf8"), ] 38 39 40if __name__ == '__main__': 41 httpd = make_server('', 8000, run_server) 42 print("Serving HTTP on port 8000...") 43 httpd.serve_forever()

View Code

从数据库查询数据填充页面

使用pymysql连接数据库:

1conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="xxx", db="xxx", charset="utf8") 2cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 3cursor.execute("select name, age, department_id from userinfo") 4user_list = cursor.fetchall() 5cursor.close() 6conn.close()

在数据库中创建一个测试表:

1CREATE TABLE user( 2 id int auto_increment PRIMARY KEY, 3 name VARCHAR(16) NOT NULL, 4 hobby VARCHAR(32) NOT NULL 5);

View Code

模板的原理就是字符串替换,我们只要在HTML页面中遵循jinja2的语法规则写上,其内部就会按照指定的语法进行相应的替换,从而达到动态的返回内容。

Django安装配置

官网下载地址==>入口

安装(要安装最新的LTS版)

发布系列

最新发布

主流支持结束

扩展支持结束

2.0

2.0.6

2018年8月

2019年4月

1.11 LTS

13年1月11日

2017年12月2日

至少在2020年4月之前

1.10

1.10.8

2017年4月4日

2017年12月2日

1.9

1.9.13

2016年8月1日

2017年4月4日

1.8 LTS

19年8月1日

2015年12月1日

2018年4月1日

1.7

1.7.11

2015年4月1日

2015年12月1日

1.6

1.6.11

2014年9月2日

2015年4月1日

1.5

1.5.12

2013年11月6日

2014年9月2日

1.4 LTS

1.4.22

2013年2月26日

2015年10月1日

1.3

1.3.7

2012年3月23日

2013年2月26日

pip3 install django==1.11.13

创建Django项目

使用下列命令创建了一个名为"mysite"的Django 项目:

django-admin startproject mysite

使用pycharm创建项目:

运行Django项目

python manage.py runserver 127.0.0.1:8000

模板文件配置

1TEMPLATES = [ 2 { 3 'BACKEND': 'django.template.backends.django.DjangoTemplates', 4 'DIRS': [os.path.join(BASE_DIR, "template")], # template文件夹位置 5 'APP_DIRS': True, 6 'OPTIONS': { 7 'context_processors': [ 8 'django.template.context_processors.debug', 9 'django.template.context_processors.request', 10 'django.contrib.auth.context_processors.auth', 11 'django.contrib.messages.context_processors.messages', 12 ], 13 }, 14 }, 15]

静态文件配置

1STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀 2STATICFILES_DIRS = [ 3 os.path.join(BASE_DIR, "static"), # 静态文件存放位置 4]

刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。

1MIDDLEWARE = [ 2 'django.middleware.security.SecurityMiddleware', 3 'django.contrib.sessions.middleware.SessionMiddleware', 4 'django.middleware.common.CommonMiddleware', 5 # 'django.middleware.csrf.CsrfViewMiddleware', 6 'django.contrib.auth.middleware.AuthenticationMiddleware', 7 'django.contrib.messages.middleware.MessageMiddleware', 8 'django.middleware.clickjacking.XFrameOptionsMiddleware', 9]

Django基础必备三件套

from django.shortcuts import HttpResponse, render, redirect

HTTPresponse

内部传入一个字符串参数(响应体的内容),返回给浏览器

1def index(request): 2 # 业务逻辑代码 3 return HttpResponse("OK")

reader

-->打开一个文件将文件内容读取出来

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

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

1def index(request): 2 # 业务逻辑代码 3 return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})

redirect

接受一个URL参数,表示跳转到指定的URL。-->回复一个让浏览器请求我指定网址的响应

1def index(request): 2 # 业务逻辑代码 3 return redirect("/home/")

 运行Django项目出错原因:

1、错误:SyntaxError: Generator expression must be parenthesized

 Django安装成功,兴致勃勃的想要运行一下这个项目,一运行给我报了个这么长错误,各种有的没的解决办法都试过,最后才发现是解释器的问题,py3.7版本和Django之间有一点问题

最后换一下3.6就好了

Stack Overflow:https://stackoverflow.com/questions/48822571/syntaxerror-generator-expression-must-be-parenthezised-python-manage-py-migra

2、Django 启动时报错 UnicodeEncodeError ...

报这个错误通常是因为计算机名为中文,改成英文的计算机名重启下电脑就可以了。

Django项目目录示例

创建一个Django项目我们首先可以看到这样几个文件:

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )