python终极篇 --- django (01)

Posted 年轻a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python终极篇 --- django (01)相关的知识,希望对你有一定的参考价值。

 

    1. 下载:
        命令行: 
            pip install django==1.11.15
            pip install -i 源 django==1.11.15
        pycharm 
            settings 解释器 点+号  输入django 选择版本 
    2. 创建django项目
        1. 命令行 
            cd 保存项目的目录
            django-admin startproject 项目名
        2. pycharm
            file ——》 new project ——> 选择django  ——> 选择解释器 ——》 创建django项目
    3. 启动项目
        1. 命令行:
            cd manage.py 的目录下
            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:80 # 0.0.0.0:80
        2. pycharm
            配置项
            点绿色三角启动
    4. settings配置
        1. 静态文件
            STATIC_URL = \'/static/\'   # 别名
            STATICFILES_DIRS = [
                os.path.join(BASE_DIR,\'static\'),
                os.path.join(BASE_DIR,\'static1\'),
            ]
        2. TEMPLATES 模板 HTML文件
            DIRS [os.path.join(BASE_DIR, \'templates\')]
            
        3. 注释csrf中间件
            
        4. 数据库的配置
        
    5. URL和函数的对应关系 ——> urls.py
        urlpatterns = [
            url(r\'^admin/\', admin.site.urls),
            url(r\'^login/\', views.login),
            url(r\'^index/\', views.index),
            url(r\'^test/\', views.test)
        ]
        
    6. APP
        1. 创建APP
            1. 命令行    
                python manage.py startapp app01
            2. pycharm
                tools ——> run manage.py task ——> startapp app01
                
        2. 注册APP
            在settings.py中的INSTALLED_APPS写:
            ‘app01’ 或者 \'app01.apps.App01Config\'
            
                
    7. 使用MySQL数据库
        1. 创建一个MySQL数据库 
        2. settings的配置:
            DATABASES = {
                \'default\': {
                    \'ENGINE\': \'django.db.backends.mysql\',   # 引擎
                    \'NAME\': \'day66\',                        # 数据库名
                    \'USER\':\'root\',                          # 用户名
                    \'PASSWORD\':\'\',                          # 密码
                    \'HOST\':\'127.0.0.1\',                     # IP
                    \'PORT\': 3306,                           # 端口号
                }
            }
            
        3. 告诉django使用pymysql模块连接数据库
            在settings.py同级目录下的__init__.py中写:
                import pymysql
                pymysql.install_as_MySQLdb()
        4. 建表 在app01/models.py中写类(继承models.Model)
            class Userinfo(models.Model):
                user = models.CharField(max_length=32)  # varchar(32)
                pwd = models.CharField(max_length=32)
        5. 执行数据库迁移命令
            python manage.py makemigrations  # 记录models.py中类是不是有变化 将变化的内容记录下来 
            python manage.py migrate         # 将model的变更同步到数据库中  
            
    8. ORM 
        对象和关系型数据库的映射  通过操作对象的方式来操作数据库
        
        映射关系;
            类    —— 》  数据表
            对象  —— 》  数据行
            属性  —— 》  字段
            
        ORM能做的事:
            操作数据表 
            操作数据行
            
        ORM操作:
            from login import models
            # 获取所有数据
            models.Userinfo.objects.all()        ——》 Queryset 
            # 获取一条数据
            models.Userinfo.objects.get(user=\'alex\',pwd=\'alexdsb\')
            取不到数据或者取到多条数据的时候报错
            # 创建一条数据
            models.Userinfo.objects.create(user=\'alex\',pwd=\'alexdsb\')
              
    9. form表单
    
        1. method=\'post\' action=\'\'  请求方式  提交数据的地址
        2. 所有的input的标签要有name属性
        3. 有一个input的type=‘submit’  或者有一个button按钮 
        
    10. GET 和 POST  
        GET:获取一个页面
         ?key1=v1&key2=v2
        
        
        POST: 提交数据
        
    11. views.py  写函数
        request  跟请求相关的所有内容
            request.method   字符串  请示方式 GET/POST
            request.POST     POST请求提交的数据    字典 
            request.GET      GET请求提交的数据
            
        返回值
        from django.shortcuts import HttpResponse,render,redirect 
        
        HttpResponse(\'字符串\')            ——》 页面显示的就是\'字符串\'
        render(request,\'模板文件名\')    ——》 渲染你的HTML文件返回给浏览器
        redirect(\'要跳转的URL\')         ——》 重定向  告诉浏览器再向URL再发一次GET请求
主要内容概括

 

 

 

服务端与浏览器收发信息:

socket 套接字 是应用层和传输层之间一个虚拟层,是一个接口.

import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 80))  
sk.listen()  
  
  
while True:  
    conn, addr = sk.accept()  
    data = conn.recv(8096)  
    conn.send(b"OK")  
    conn.close()  

 

打印一下收到的消息是什么>???

将\\r\\n替换成换行看得更清晰点:

GET / HTTP/1.1  
Host: 127.0.0.1:8080  
Connection: keep-alive  
Cache-Control: max-age=0  
Upgrade-Insecure-Requests: 1  
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3355.4 Safari/537.36  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8  
Accept-Encoding: gzip, deflate, br  
Accept-Language: zh-CN,zh;q=0.9  
Cookie: csrftoken=CtHePYARJOKNx5oNVwxIteOJXpNyJ29L4bW4506YoVqFaIFFaHm0EWDZqKmw6Jm8  

那浏览器收到的消息是什么?

 

通过以上对比,发现收发消息的格式都是一样的---即为 HTTP协议格式

每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。

HTTP响应的Header中有一个 Content-Type表明响应的内容格式。它的值如text/html; charset=utf-8。

text/html则表示是网页,charset=utf-8则表示编码为utf-8。

 

 

  

mport socket    
    
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    
sock.bind((\'127.0.0.1\', 8000))    
sock.listen()    
    
while True:    
    conn, addr = sock.accept()    
    data = conn.recv(8096)    
    # 给回复的消息加上响应状态行    
    conn.send(b"HTTP/1.1 200 OK\\r\\n\\r\\n")      不加这行代码返回不了数据
    conn.send(b"OK")    
    conn.close()    
自定义web框架
""" 
根据URL中不同的路径返回不同的内容 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
sk.listen()  # 监听  
  
while True:  
    # 等待连接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客户端发来的消息  
    # 从data中取到路径  
    data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    # 按\\r\\n分割  
    data1 = data.split("\\r\\n")[0]  
    url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    conn.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    # 根据不同的路径返回不同内容  
    if url == "/index/":  
        response = b"index"  
    elif url == "/home/":  
        response = b"home"  
    else:  
        response = b"404 not found!"  
  
    conn.send(response)  
    conn.close()  
根据不同的路径返回不同的内容
""" 
根据URL中不同的路径返回不同的内容--函数版 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
sk.listen()  # 监听  
  
  
# 将返回不同的内容部分封装成函数  
def func(url):  
    s = "这是{}页面!".format(url)  
    return bytes(s, encoding="utf8")  
  
  
while True:  
    # 等待连接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客户端发来的消息  
    # 从data中取到路径  
    data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    # 按\\r\\n分割  
    data1 = data.split("\\r\\n")[0]  
    url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    conn.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    # 根据不同的路径返回不同内容,response是具体的响应体  
    if url == "/index/":  
        response = func(url)  
    elif url == "/home/":  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    conn.send(response)  
    conn.close()  
根据不同的路径返回不同的内容--函数版
""" 
根据URL中不同的路径返回不同的内容--函数进阶版 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
sk.listen()  # 监听  
  
  
# 将返回不同的内容部分封装成不同的函数  
def index(url):  
    s = "这是{}页面XX!".format(url)  
    return bytes(s, encoding="utf8")  
  
  
def home(url):  
    s = "这是{}页面。。!".format(url)  
    return bytes(s, encoding="utf8")  
  
  
# 定义一个url和实际要执行的函数的对应关系  
list1 = [  
    ("/index/", index),  
    ("/home/", home),  
]  
  
while True:  
    # 等待连接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客户端发来的消息  
    # 从data中取到路径  
    data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    # 按\\r\\n分割  
    data1 = data.split("\\r\\n")[0]  
    url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    conn.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    # 根据不同的路径返回不同内容  
    func = None  # 定义一个保存将要执行的函数名的变量  
    for item in list1:  
        if item[0] == url:  
            func = item[1]  
            break  
    if func:  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    # 返回具体的响应消息  
    conn.send(response)  
    conn.close()  
根据不同的路径返回不同的内容--函数进阶版

 

""" 
根据URL中不同的路径返回不同的内容--函数进阶版 
返回独立的HTML页面 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
sk.listen()  # 监听  
  
  
# 将返回不同的内容部分封装成不同的函数  
def index(url):  
    # 读取index.html页面的内容  
    with open("index.html", "r", encoding="utf8") as f:  
        s = f.read()  
    # 返回字节数据  
    return bytes(s, encoding="utf8")  
  
  
def home(url):  
    with open("home.html", "r", encoding="utf8") as f:  
        s = f.read()  
    return bytes(s, encoding="utf8")  
  
  
# 定义一个url和实际要执行的函数的对应关系  
list1 = [  
    ("/index/", index),  
    ("/home/", home),  
]  
  
while True:  
    # 等待连接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客户端发来的消息  
    # 从data中取到路径  
    data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    # 按\\r\\n分割  
    data1 = data.split("\\r\\n")[0]  
    url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    conn.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    # 根据不同的路径返回不同内容  
    func = None  # 定义一个保存将要执行的函数名的变量  
    for item in list1:  
        if item[0] == url:  
            func = item[1]  
            break  
    if func:  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    # 返回具体的响应消息  
    conn.send(response)  
    conn.close()  
返回具体的HTML文件
<!DOCTYPE html>
<html lang="en">
<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>index</title>
</head>
<body>
<div>这是index页面</div>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<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>index</title>
</head>
<body>
<div>这是home页面</div>
</body>
</html>
home.html

 

""" 
根据URL中不同的路径返回不同的内容--函数进阶版 
返回独立的HTML页面 
"""  
  
import socket  
  
sk = socket.socket()  
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
sk.listen()  # 监听  
  
  
# 将返回不同的内容部分封装成不同的函数  
def index(url):  
    # 读取index.html页面的内容  
    with open("index.html", "r", encoding="utf8") as f:  
        s = f.read()  
    # 返回字节数据  
    return bytes(s, encoding="utf8")  
  
  
def home(url):  
    with open("home.html", "r", encoding="utf8") as f:  
        s = f.read()  
    return bytes(s, encoding="utf8")  
  
  
def timer(url):  
    import time  
    with open("time.html", "r", encoding="utf8") as f:  
        s = f.read()  
        s = s.replace(\'@@time@@\', time.strftime("%Y-%m-%d %H:%M:%S"))  
    return bytes(s, encoding="utf8")  
  
  
# 定义一个url和实际要执行的函数的对应关系  
list1 = [  
    ("/index/", index),  
    ("/home/", home),  
    ("/time/", timer),  
]  
  
while True:  
    # 等待连接  
    conn, add = sk.accept()  
    data = conn.recv(8096)  # 接收客户端发来的消息  
    # 从data中取到路径  
    data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    # 按\\r\\n分割  
    data1 = data.split("\\r\\n")[0]  
    url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    conn.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    # 根据不同的路径返回不同内容  
    func = None  # 定义一个保存将要执行的函数名的变量  
    for item in list1:  
        if item[0] == url:  
            func = item[1]  
            break  
    if func:  
        response = func(url)  
    else:  
        response = b"404 not found!"  
  
    # 返回具体的响应消息  
    conn.send(response)  
    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. 让网页动态起来  
  5. wsgiref模块版  
  6. """   
  7.      
  8. from wsgiref.simple_server import make_server   
  9.      
  10.      
  11. # 将返回不同的内容部分封装成函数   
  12. def index(url):   
  13.     # 读取index.html页面的内容   
  14.     with open("index.html", "r", encoding="utf8") as f:   
  15.         s = f.read()   
  16.     # 返回字节数据   
  17.     return bytes(s, encoding="utf8")   
  18.      
  19.      
  20. def home(url):   
  21.     with open("home.html", "r", encoding="utf8") as f:   
  22.         s = f.read()   
  23.     return bytes(s, encoding="utf8")   
  24.      
  25.      
  26. def timer(url):   
  27.     import time   
  28.     with open("time.html", "r", encoding=以上是关于python终极篇 --- django (01)的主要内容,如果未能解决你的问题,请参考以下文章

    python 终极篇 cookie与session

    Django 框架篇: django自带的认证系统

    01-Django-基础篇-Web框架简介

    大数据之---Hive全网最详细的编译tar及部署终极篇

    Python之路第十八章:Django基础篇

    python3之Django基础篇