01-Django初识

一、知识回顾

  1、python基础

  2、网络编程

  3、并发编程

  4、前端

  5、数据库(MySQL)

二、今日概要

  1、Web框架的本质

  2、Django简介及安装使用

三、今日详细

  1、Web应用

    Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。

    应用程序有两种模式C/S、B/S:

  • C/S(Client/Server)是客户端/服务器端程序,也就是说这类程序一般独立运行。
  • B/S(Browser/Server)就是浏览器端/服务器端应用程序,这类应用程序一般借助谷歌,火狐等浏览器来运行。

    Web应用程序一般是B/S模式。Web应用程序首先是“应用程序”,和用什么程序语言(如:java,python等)编写出来的程序没有什么本质上的不同。在网络编程的意义下,浏览器是一个socket客户端,服务器是一个socket服务端。

import socket
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口
sock.bind(("127.0.0.1", 8888))

# 监听
sock.listen(5)

while True:
    conn, addr = sock.accept()  # 等待连接

    data = conn.recv(1024)  # 接收数据
    print("请求信息====>  %s" % data)

    # 发送数据
    conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\n\r\n".encode('utf-8'))
    conn.send("<h1>Welcome to 路飞学城</h1>".encode("utf-8"))
    conn.close()

   2、Http协议简介

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。  

    HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

    具体的内容请移步查看详情:点我啊!

  补充内容:对URL的认识

    URL是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。

    URL的组成部分(如:http://www.luffycity.com/home):

      a、协议部分:在Internet中可以使用多种协议,如HTTP,FTP等等。上面的例子中“http”就是在声明协议,在"http"后面的“//”为分隔符。

      b、域名部分:上面的例子URL的域名部分为“www.luffycity.com”。一个URL中,也可以使用IP地址作为域名使用(域名通过dns解析,最终访问的还是IP地址)。

      c、端口部分:紧跟域名后面的就是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口(80)。

      d、路径部分:以“/”字符区别路径中的每一个目录名称(如:http://www.luffycity.com/home,中的home就是路径名称)。

      e、文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分(如:https://hcdn1.luffycity.com/static/frontend/index/Luffy-study-logo.png)。本例中的文件名是“Luffy-study-logo.png”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名。

      f、锚部分:从“#”开始到最后,都是锚部分。锚部分也不是一个URL必须的部分。我们一起学猫叫

      g、参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

  3、根据不同路径返回不同内容

import socket
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口
sock.bind(("127.0.0.1", 8888))

# 监听
sock.listen(5)

while True:
    conn, addr = sock.accept()  # 等待连接

    data = conn.recv(1024)  # 接收数据
    data = data.decode("utf-8")
    data_list = data.split()
    url = data_list[1] if data_list else None
    print("请求信息====>  %s" % url)

    # 发送数据
    conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\n\r\n".encode('utf-8'))

    if url == "/index":
        conn.send("<h1>Welcome to 路飞学城</h1>".encode("utf-8"))
    elif url == "/japan":
        conn.send("<h2>---日韩专区---</h2>".encode("utf-8"))
    elif url == "/american":
        conn.send("<h2>---欧美专区---</h2>".encode("utf-8"))
    else:
        conn.send("<h2 style='color:red'>404 not found !</h2>".encode("utf-8"))
    conn.close()

  4、根据不同路径返回不同内容(函数版)

import socket
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口
sock.bind(("127.0.0.1", 8888))

# 监听
sock.listen(5)


def index(url):
    ret = "<h1>Welcome to 路飞学城   url ===> {}</h1>".format(url)
    return ret.encode("utf-8")


def american(url):
    ret = "<h2>---欧美专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


def japan(url):
    ret = "<h2>---日韩专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


while True:
    conn, addr = sock.accept()  # 等待连接

    data = conn.recv(1024)  # 接收数据
    data = data.decode("utf-8")
    data_list = data.split()
    url = data_list[1] if data_list else None
    print("请求信息====>  %s" % url)

    # 发送数据
    conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\n\r\n".encode('utf-8'))

    if url == "/index":
        ret = index(url)
    elif url == "/japan":
        ret = japan(url)
    elif url == "/american":
        ret = american(url)
    else:
        ret = "<h2 style='color:red'>404 not found !</h2>".encode("utf-8")
    conn.send(ret)

    conn.close()

  5、根据不同路径返回不同内容(函数进阶版)

import socket
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口
sock.bind(("127.0.0.1", 8888))

# 监听
sock.listen(5)


def index(url):
    ret = "<h1>Welcome to 路飞学城   url ===> {}</h1>".format(url)
    return ret.encode("utf-8")


def american(url):
    ret = "<h2>---欧美专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


def japan(url):
    ret = "<h2>---日韩专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


url_list = [
    ("/index", index),
    ("/american", american),
    ("/japan", japan),
]


while True:
    conn, addr = sock.accept()  # 等待连接

    data = conn.recv(1024)  # 接收数据
    data = data.decode("utf-8")
    data_list = data.split()
    url = data_list[1] if data_list else None
    print("请求信息====>  %s" % url)

    # 发送数据
    conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\n\r\n".encode('utf-8'))

    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    if func:
        ret = func(url)
    else:
        ret = "<h2 style='color:red'>404 not found !</h2>".encode("utf-8")
    conn.send(ret)

    conn.close()

  6、返回一个HTML文件内容

<!--index.html文件内容-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>Welcome to 路飞学城首页</h1>
</body>
</html>
import socket
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口
sock.bind(("127.0.0.1", 8888))

# 监听
sock.listen(5)


def index(url):
    with open("index.html", "rb") as f:
        ret = f.read()
    return ret


def american(url):
    ret = "<h2>---欧美专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


def japan(url):
    ret = "<h2>---日韩专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


url_list = [
    ("/index", index),
    ("/american", american),
    ("/japan", japan),
]


while True:
    conn, addr = sock.accept()  # 等待连接

    data = conn.recv(1024)  # 接收数据
    data = data.decode("utf-8")
    data_list = data.split()
    url = data_list[1] if data_list else None
    print("请求信息====>  %s" % url)

    # 发送数据
    conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\n\r\n".encode('utf-8'))

    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    if func:
        ret = func(url)
    else:
        ret = "<h2 style='color:red'>404 not found !</h2>".encode("utf-8")
    conn.send(ret)

    conn.close()

  7、返回一个动态HTML文件内容

<!--timer.html文件内容-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <!--此处使用“@@time@@”作为占位符-->
    <h2>bobo为您报时,现在是北京时间:@@time@@</h2>
</body>
</html>
import socket
import time
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP和端口
sock.bind(("127.0.0.1", 8888))

# 监听
sock.listen(5)


def index(url):
    with open("timer.html", "rb") as f:
        ret = f.read()
    return ret


def american(url):
    ret = "<h2>---欧美专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


def japan(url):
    ret = "<h2>---日韩专区---   url ===> {}</h2>".format(url)
    return ret.encode("utf-8")


def timer(url):
    with open("timer.html", "r", encoding="utf-8") as f:
        data = f.read()
        now_time = time.strftime("%Y-%m-%d %H:%M:%S")
        data = data.replace("@@time@@", now_time)
    return data.encode("utf-8")


url_list = [
    ("/index", index),
    ("/american", american),
    ("/japan", japan),
    ("/timer", timer),
]


while True:
    conn, addr = sock.accept()  # 等待连接

    data = conn.recv(1024)  # 接收数据
    data = data.decode("utf-8")
    data_list = data.split()
    url = data_list[1] if data_list else None
    print("请求信息====>  %s" % url)

    # 发送数据
    conn.send("HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\n\r\n".encode('utf-8'))

    func = None
    for i in url_list:
        if url == i[0]:
            func = i[1]
            break
    if func:
        ret = func(url)
    else:
        ret = "<h2 style='color:red'>404 not found !</h2>".encode("utf-8")
    conn.send(ret)

    conn.close()

   总结:web框架,其本质就是socket服务端。

  web框架的功能:

    1、socket收发消息

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

    3、返回动态页面(字符串的替换——模板渲染)

  web常用框架分类:

    Django: 2、3

    flask: 2

    tornado: 1、2、3

   8、服务器程序和应用程序

    对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。

    服务器程序主要负责对socket服务端进行封装,并在请求到来时,对请求的各种数据进行处理。

    应用程序则主要负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、 Tornado等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。

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

    常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。

    好了,接下来我们就使用wsgiref模块来替换我们自己写的web框架的socket server部分,请看下面的代码。

import time
from wsgiref.simple_server import make_server


# 将返回不同的内容部分封装成函数
def index(url):
    # 读取index.html页面的内容
    with open("index.html", "r", encoding="utf-8") as f:  # 此处的HTML文件,同上
        data = f.read()
        # 返回字节数据
    return data.encode("utf-8")


def timer(url):
    with open("timer.html", "r", encoding="utf-8") as f:  # 此处的HTML文件,同上
        data = f.read()
        now_time = time.strftime("%Y-%m-%d %H:%M:%S")
        data = data.replace("@@time@@", now_time)
    return data.encode("utf-8")


# 定义一个url和实际要执行的函数的对应关系
url_list = [
    ("/index", index),
    ("/timer", timer),
]


def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 设置HTTP响应的状态码和头信息
    url = environ['PATH_INFO']  # 取到用户输入的url
    func = None
    for i in url_list:
        if i[0] == url:
            func = i[1]
            break
    if func:
        ret = func(url)
    else:
        ret = "<h2 style='color:red'>404 not found !</h2>".encode("utf-8")
    return [ret, ]


if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8080, run_server)
    print("我在8080等你哦...")
    httpd.serve_forever()

  9、jinja2模块

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

    下载jinja2:

pip install jinja2

    下面咱们通过代码,揭开神秘面纱来见识一下jinja2的芳容。

<!--home.html文件内容-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h2>姓名:{{name}}</h2>
    <h2>爱好:</h2>
    <ul>
        {% for hobby in hobby_list %}
            <li>{{hobby}}</li>
        {% endfor %}
    </ul>
</body>
</html>
from wsgiref.simple_server import make_server
from jinja2 import Template


def home(url):
    with open("home.html", "r", encoding="utf-8") as f:
        data = f.read()
        templata = Template(data)
        ret = templata.render({"name": "于谦", "hobby_list": ["抽烟", "喝酒", "烫头"]})
    return ret.encode("utf-8")


url_list = [
    ("/home", home),
]


def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 设置HTTP响应的状态码和头信息
    url = environ['PATH_INFO']  # 取到用户输入的url
    func = None
    for i in url_list:
        if i[0] == url:
            func = i[1]
            break
    if func:
        ret = func(url)
    else:
        ret = "<h2 style='color:red'>404 not found !</h2>".encode("utf-8")
    return [ret, ]


if __name__ == '__main__':
    httpd = make_server("127.0.0.1", 8989, run_server)
    print("我在8989等你哦...")
    httpd.serve_forever()

    上面的例子,咱们是在代码里写死的内容,我们思考一下,可不可以从数据库获取数据,来进行页面上内容的替换呢?

    总结:

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

  哎呀,前戏总算结束了,下面终于可以……

  Django

  有请进入Django官网下载页面:猛戳一下

  1、安装Django(建议安装最新LTS版本):

pip3 install django==2.1.7

  2、创建咱们第一个Django项目:

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

django-admin startproject mysite

  3、Django项目目录介绍:

|---mysite  # 项目的/目录
	|---mysite  # 项目目录
		|---__init__.py
		|---settings.py  # 配置文件
		|---urls.py  # 路由系统 ===> url与视图的对应关系
		|---wsgi.py  # runserver命令就使用wsgiref模块做简单的web server
	|---manage.py  # 管理文件

  4、启动运行Django项目:

python manage.py runserver                # 127.0.0.1:8000
python manage.py runserver 80             # 127.0.0.1:80
python manage.py runserver 0.0.0.0:8888   # 0.0.0.0:8888
# 注意:要在manage.py同级目录执行命令

  5、Django配置文件:

# 模板文件配置
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "template")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# 静态文件配置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "statics"),
]

  6、写自己的第一个页面,感受一下。

四、今日作业

  基于Django,使用bootstrap来写一个用户登录页面

 

 

 

 

 

 

 

 

  一起喵喵喵喵喵!!!

    我要回去!

posted @ 2018-11-27 16:44  Michael--chen  阅读(196)  评论(0编辑  收藏  举报