来自作者:金角大王

本节内容

Http原理介绍

自行开发一个Web框架

WSGI介绍

Django介绍

MVC/MTV

Django安装

创建项目与APP

开发第一个页面

为什么学Django?

Good question , 知Python者必知Django, 因为这可是Python语言里最流行&强大的Web框架,同时亦是全球第5大WEB框架,可快速构建稳定强大的WEB项目,大大提高开发效率,很多知名项目都是基于Django开发,如Disqus、Pinterest、Instagram、Bitbucket等, Django官方Slogan是The framework for perfectionist with deadline! 一个为完美主义者且又开发工期很紧的人设计的框架,事实确实如此,Django自身集成了丰富的WEB开发通用组件,如用户认证、分页、中间件、缓存、session等,可以避免浪费大量时间重复造轮子。

Http原理介绍

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。

HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。如下图所示:

HTTP协议永远都是客户端发起请求,服务器回送响应。见下图:

这个Client和Server端本质上是一个Socket客户端和服务器端,Http协议可以说是基于Socket的再上层封装。

HTTP特性

基于TCP/IP协议

你每次打开百度或其它网站,都需要先建立好TCP/IP会话,当然这个浏览器会帮你做了。

短连接

你打开 https://www.luffycity.com/  或其它网站, 当服务器端把这个页面的内容全返回后,就把这次连接断开了,会话就结束了,你在浏览器上看到页面内容已经是下载到本地的了,所以此时如果服务器端更新了内容,你本地的页面自然是不会跟着变的。除非你再刷新一下,这样就又进行了一次会话。那为何是短连接呢?你想一想

被动响应

这个很好理解,你不请求百度,百度是不会主动连接你的。

无状态

无状态是指,当浏览器发送请求给服务器的时候,服务器响应,但是同一个浏览器再发送请求给服务器的时候,他会响应,但是他不知道你就是刚才那个浏览器,简单地说,就是服务器不会去记得你,所以是无状态协议。

自行开发一个Web Server

既然Http协议本质上是基于Socket做的,我们又学过Socket了,那能不能自己开发一个Web Server呢? 回答是of course.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding:utf-8 -*-
# created by Alex Li - 路飞学城
 
import socket
 
 
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('localhost'8000))
    sock.listen(5)
 
    while True:
        # 等待浏览器访问
        conn, addr = sock.accept()
        # 接收浏览器发送来的请求内容
        data = conn.recv(1024)
        print(data)
 
        # 给浏览器返回内容
        conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n")
        conn.send("电脑前的你长的真好看!".encode("utf-8"))
 
        # 关闭和浏览器创建的socket连接
        conn.close()
 
 
if __name__ == "__main__":
    main()

  

我靠,这么简单,是的,就这么简单,但你现在只是返回了一句话,如果是要返回一个图片呢?一个文件呢?这就涉及你自己要负责实现文件的传送了,我们学socket传文件时,遇到过粘包问题,解决起来挺麻烦的,你现在要自己通过Socket把Http协议里的各种功能都实现了的话,估计孩子都长大了。与其浪费时间自己写,不如直接用先人的。

WSGI介绍

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

通俗的说:当规范建立后,程序就不再重复编写web server(socket服务端),而是直接使用现成的实现WSGI的模块(例如:wsgiref、uwsgi、werkzeug),从而让程序员更加专注与业务代码

与其重复造轮子,不如直接用现成的。

Python的wsgiref是基于WSGI规范封装的模块,我们可以在这个模块基础上开发我们的web server

基于WSGI开发一个WEB服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding:utf-8 -*-
# created by Alex Li - 路飞学城
 
from wsgiref.simple_server import make_server
 
 
def run_server(environ, start_response):
    """
    当有用户在浏览器上访问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器
    :param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
    :param start_response: 响应相关
    :return:
    """
 
    start_response('200 OK',[('Content-Type''text/html;charset=utf-8')])
    return [bytes('<h1>我旁边的这个人长的真丑呀!!',encoding='utf-8'),]
 
if __name__ == '__main__':
    httpd = make_server('localhost',8001,run_server)
    httpd.serve_forever()

别人家的网站和我们的网站  

你看别人的网站,可以根据URL不同看到不同的内容,比如这个:煎蛋网

但我们刚才自己开发的网站,永远只能看到同样的内容。

怎么办?我们自己也可以处理url呀

 1 # -*- coding:utf-8 -*-
2 # created by Alex Li - 路飞学城
3
4 from wsgiref.simple_server import make_server
5
6
7 def western():
8 return "欢迎来到欧美专区"
9
10 def japan():
11 return "欢迎来到日本人专区"
12
13
14 def routers():
15 """负责把url与对应的方法关联起来"""
16 urlpatterns = (
17 ('/western/',western),
18 ('/japan/',japan),
19 )
20
21 return urlpatterns
22
23
24 def run_server(environ, start_response):
25 """
26 当有用户在浏览器上访问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器
27 :param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
28 :param start_response: 响应相关
29 :return:
30 """
31 start_response('200 OK',[('Content-Type', 'text/html;charset=utf-8')])
32 url = environ.get("PATH_INFO")
33 urlpatterns = routers()
34
35 func = None
36
37 for item in urlpatterns:
38 if item[0] == url:
39 func = item[1]
40 break
41 if func:
42 return [bytes(func(),encoding="utf-8"),]
43 else:
44 return [bytes('404 not found.',encoding="utf-8"),]
45
46 if __name__ == '__main__':
47 httpd = make_server('localhost',8001,run_server)
48 httpd.serve_forever()

真棒,轻松的就可以使你的web server支持多页面了。但你高兴不起来,因为你看到人家别人的网站多姿多彩,各种图片、各种动效,你的网站只能显示文字。感觉像是上个世纪的产物,不刺激,哈,那就来点刺激的,让你的网站也支持一下图片和样式。

 1 # -*- coding:utf-8 -*-
2 # created by Alex Li - 路飞学城
3
4 from wsgiref.simple_server import make_server
5 import re ,os
6 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
7
8
9 def img_handler(url):
10 img_relative_path = re.sub("/static/","imgs/",url,count=1)
11 img_path = os.path.join(BASE_DIR,img_relative_path)
12 print('img',BASE_DIR,img_path)
13 f = open(img_path,'rb')
14 data = f.read()
15 f.close()
16 return data
17
18
19 def western():
20 data = '''
21 <h1>欢迎来到欧美专区</h1>
22
23 <img src='/static/test_america.jpg' width='800px'/>
24
25 '''
26
27 return data
28
29
30 def japan():
31 data = '''
32 <h1>欢迎来到日本人专区</h1>
33
34 <img src='/static/testimg.gif' />
35
36 '''
37
38 return data
39
40
41 def routers():
42 """负责把url与对应的方法关联起来"""
43 urlpatterns = (
44 ('/western/',western),
45 ('/japan/',japan),
46 )
47
48 return urlpatterns
49
50
51 def run_server(environ, start_response):
52 """
53 当有用户在浏览器上访问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器
54 :param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等
55 :param start_response: 响应相关
56 :return:
57 """
58 content_type = 'text/html;charset=utf-8'
59
60
61 url = environ.get("PATH_INFO")
62 urlpatterns = routers()
63
64 func = None
65 if url.startswith('/static/'): #代表是张图片
66 content_type = 'text/jpg;charset=utf-8'
67 start_response('200 OK', [('Content-Type', content_type)])
68
69 img_data = img_handler(url)
70 return [img_data, ]
71
72 else:
73 for item in urlpatterns:
74 if item[0] == url:
75 func = item[1]
76 break
77
78 start_response('200 OK', [('Content-Type', content_type)])
79 if func:
80 return [bytes(func(),encoding="utf-8"),]
81 else:
82 return [bytes('404 not found.',encoding="utf-8"),]
83
84 if __name__ == '__main__':
85 httpd = make_server('localhost',8001,run_server)
86 httpd.serve_forever()

执行一下看看。

真是技术改变生活呀!

能显示图片只是冰山一角,我们需要继续开发一下功能:

  • 用户表单提交,即:用户向后台发送表单数据
  • 数据库操作
  • 加载样式和JS文件
  • 允许用户下载文件

虽然自己开发有乐趣,但确实比较麻烦,在项目开发中,追求的更多是效率,而不是乐趣,所以还是尽量不要重复造轮子啦,我们接下来要学的Django框架就是帮我们已经造好的轮子。

Web框架的本质

虽然自己写Web Server比较麻烦,但是我们从中也了解web框架的本质:

  1. 浏览器是socket客户端,网站是socket服务端
  2. wsgi,是一个规范,wsgiref实现了这个规范并在其内部实现了socket服务端
  3. 根据 url 的不同执行不同函数,即:路由系统
  4. 函数,即:视图函数
  5. 图片、css、js文件 统一称为静态文件,需要读取内容直接返回给用户浏览器

Django来了

安装

1
pip3 install django   #目前最新版本是2.0

* 注意,2.0 跟1.x版本上用法上是有些区别的,本课程我们主讲2.x。

安装成功后,就会出现 django-admin 命令

创建Project

你想做个网站,首先我们要创建一个django project, 以后的代码都放在这个项目里。

1
django-admin  startproject  mysite #项目名是mysite  

创建好的项目目录结构

1
2
3
4
5
6
7
8
9
        mysite
        ├── manage.py       # 管理程序的文件,启动和结束等。
        └── my site
            ├── __init__.py
            ├── settings.py     # 程序的配置文件
            ├── urls.py     # 程序的路由系统,即:url和处理其函数的对应的关系
            └── wsgi.py     # 指定框架的wsgi
 
命令帮助我们创建了几个文件,通过文件将功能代码归类。  

创建APP

一个项目中会包含一个或多个子项目,每个项目实现不同的功能和服务,如微信里包含基本通信功能,还有支付、小程序等,每块业务都可以分为一个子项目。在django中, 我们管这个子项目叫app。下面是一个有多app的项目

为了开发和维护方便,每个子项目(app)都会有一个独立文件夹来存放各自的业务代码。
一般程序简单情况下,只需要创建一个app即可。

1
python manage.py startapp app01   #app01 是app名称

Django的第一次请求  

HTTP请求本质

上面的一次django请求都经历了哪些过程呢?我们来剖析下

浏览器访问网站的本质:socket客户端、socket服务端之间的收发消息。

流程:

1. 【服务端】网站启动,并监听IP和端口,如:127.0.0.1:80,等待客户端来连接…

2. 【客户端】浏览器中输入http://www.oldboyedu.com/index/,浏览器先后进行:

  1.   连接:域名解析得到网站IP,并根据端口进行连接。
  2.   发送消息:将请求数据发送给服务端,发送数据本质上是字符串,格式如下:
1
2
GET /index/ http1.1\r\nhost:www.luffycity.com…..\r\n\r\n
                             
POST /index/ http1.1\r\nhost:www.luffycity.com...\r\n\r\nage=18&num=13.

3. 【服务端】接收用户请求发来的数据,并根据请求字符串解析,并做出响应。  

1
响应:HTTP/1.1 200 OK\r\nContent-Type: text/html;...\r\n\r\n<html>...</html>

4. 【客户端】接收服务端响应的内容,将响应体展示在浏览器上,响应头偷偷保存到浏览器。

5. 【客户端】【服务端】连接断开,Http请求终止(体现了Http短连接)。  

注意:请求和响应基本包含请求头和请求体并通过\r\n\r\n进行分割。

用Django 开发用户登录页面

用户登录是个表单啦,但目前我们只会用Django返回字符串,表单涉及的html元素比较多,总不能在view.py里写好返回吧?这太low了,是的,怎么可以不low? 是时候表演真正的技术啦。

Django有个叫模板(Template)的东东,可以直接把你的Html代码写在模板里,返回给浏览器。

模板初探

想用模板仅需2步,

  1. 配置存html文件的模板目录
  2. 在你的views.py的响应函数里返回对应的html文件

是时候该讲讲套路啦

刚才在开发用户登录页面时,我们的请求处理流程是这样的, 请求-> url.py -> views.py -> template -> 浏览器, 流程为什么这样安排?中间如何要从数据库里拿数据,是应该在哪个阶段?其实Django或其它web语言的web框架在开发时都符合了某种神秘的套路,这个套路是什么?即MVC.

MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式

不懂对不对?其实说白了,就是把Web开发中一个请求处理流程分成了3部分,每部分专注做自己的事。

  1. Model(模型)一般对应数据库操作、纪录的存取
  2. View(视图)决定着如何展示数据
  3. Controller(控制器)负现处理用户交互的部分。控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

MVC & MTV 

Django是一个MTV框架,其架构模板看上去与传统的MVC架构并没有太大的区别。Django将MVC中的视图进一步分解为 Django视图 和 Django模板两个部分,分别决定 “展现哪些数据” 和 “如何展现”,使得Django的模板可以根据需要随时替换,而不仅仅限制于内置的模板。至于MVC控制器部分,由Django框架的URLconf来实现。

再具体点的图

从下一章开始 ,我们会一点点把model,views,template,url 每个都延伸开来讲。

Django 14天从小白到进阶- Day1 Django 初识的更多相关文章

  1. python框架之Django(14)-rest_framework模块

    APIView django原生View post请求 from django.shortcuts import render, HttpResponse from django import vie ...

  2. Django:学习笔记(7)——模型进阶

    Django:学习笔记(7)——模型进阶 模型的继承 我们在面向对象的编程中,一个很重要的的版块,就是类的继承.父类保存了所有子类共有的内容,子类通过继承它来减少冗余代码并进行灵活扩展. 在Djang ...

  3. day1(Django)

    1,web项目工作流程 1.1 了解web程序工作流程 1.2 django生命周期   2,django介绍 目的:了解Django框架的作用和特点作用: 简便.快速的开发数据库驱动的网站 Djan ...

  4. 12月8日内容总结——Django推导流程,Django模块的下载和基本使用、Django的应用和目录结构讲解、Django三板斧

    目录 一.纯手撸web框架 二.基于wsgiref模块 三.代码封装优化 四.动静态网页 五.jinja2模块 六.前端.后端.数据库三者联动 七.python主流web框架 八.django简介 1 ...

  5. Django 1.10中文文档—第一个Django应用Part1

    在本教程中,我们将引导您完成一个投票应用程序的创建,它包含下面两部分: 一个可以进行投票和查看结果的公开站点: 一个可以进行增删改查的后台admin管理界面: 我们假设你已经安装了Django.您可以 ...

  6. Django 2.0.1 官方文档翻译: 如何安装 django (Page 17)

    如何安装 django(Page 17) 这一部分可以让你将 Django 运行起来. 安装 Python 作为 python 的一个 web 框架,Django 依赖 Python.Python 的 ...

  7. python读书笔记-django架站过程总结(from the django book)

    django架站过程总结:1.django-admin startproject store2.store这个project的目录下有:__init__,manage,setting,urls3.se ...

  8. dya49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目

    目录 1.自定义web框架wsgiref版 2.自定义web框架wsgiref版-优化版 3.模板渲染JinJa2 4.MTV和MVC框架 5.django:下载安装&创建启动 自定义web框 ...

  9. [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]

    [Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...

  10. day49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目

    目录 1.自定义web框架wsgiref版 2.自定义web框架wsgiref版-优化版 3.模板渲染JinJa2 4.MTV和MVC框架 5.django:下载安装&创建启动 自定义web框 ...

随机推荐

  1. HAL层分析

    1. 安卓HAL模块基本 2. 定义hal层代码的5个特性 1)硬件抽象层具有与硬件的密切相关性. 2) 硬件抽象层具有与操作系统无关性. 3) 接口定义的功能应该包含硬件或者系统所需硬件支持的所有功 ...

  2. UGUI按Tab键切换输入框

    脚本挂在输入框的父物体上即可 [code]csharpcode: using System.Collections; using System.Collections.Generic; using U ...

  3. 1 关于win10原生系统下 OCRmyPDF安装使用

    win10原生系统下 OCRmyPDF安装使用长期以来一直在代替freepic2pdf的工具,因为在图片转化PDF时,如果没有勾选该软件 添加OCR层 选项,印象中事后无法挂OCR层上去.福昕风腾,A ...

  4. MFC 与 C++ 类型转换

    C++ 中到的类型转换很多,先记录下来,多了写成一个类 1.CString转int 1 CString cNum="9527"; 2 int iNum = 0; 3 iNum=at ...

  5. 学会规则引擎Drools,让你早点下班

    前言 现在有这么个需求,网上购物,需要根据不同的规则计算商品折扣,比如VIP客户增加5%的折扣,购买金额超过1000元的增加10%的折扣等,而且这些规则可能随时发生变化,甚至增加新的规则.面对这个需求 ...

  6. badapple最后一步,讲黑白图转为字符图,然后输出就行了。

    from PIL import Image import os char_s = list(" .,-'`:!1+*abcdefghijklmnopqrstuvwxyz<>()\ ...

  7. 大数据 Hadoop 的五大优势

    Hadoop与竞争对手相比有哪些优势? 到目前为止,人们可能已经听说过ApacheHadoop.这个名字来源于一只可爱的玩具大象,但Hadoop只不过是一个毛绒玩具.Hadoop是一个开源软件项目,它 ...

  8. java面向对象-基础入门

    java面向对象-基础入门 面向过程:线性思维 面向对象思维:物以类聚,分类的思维 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统,但是具体到某个微观 ...

  9. 美团面试:熟悉哪些JVM调优参数?

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

  10. AndroidBanner - ViewPager 03

    AndroidBanner - ViewPager 03 上一篇文章,描述了如何实现自动轮播的,以及手指触摸的时候停止轮播,抬起继续轮播,其实还遗留了一些问题: 当banner不可见的时候,也需要停止 ...