zoukankan      html  css  js  c++  java
  • Django学习笔记1

    Web框架本质

    所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 这样我们就可以自己实现Web框架了。我们定义一个socket server端程序,与浏览器(client端)进行互交试试

    import socket
    
    sk = socket.socket()
    sk.bind(("127.0.0.1", 8001))
    sk.listen()
    
    
    while True:
        conn, addr = sk.accept()
        data = conn.recv(8096)
        print(data)  # 将浏览器发来的消息打印出来
        conn.send(b"OK")
        conn.close()

    b'GET / HTTP/1.1
    Host: 127.0.0.1:8001
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    DNT: 1
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: csrftoken=RKBXh1d3M97iz03Rpbojx1bR6mhHudhyX5PszUxxG3bOEwh1lxFpGOgWN93ZH3zv
    
    '

    服务端收到了http的请求头,如此就可以和客户端进行互交了。所以可以说Web服务本质上都是在这十几行代码基础上扩展出来的,只要请求和响应满足一定的规范(http协议),就可以实现我们写的server端和client端进行互交了。

    HTTP协议详解:https://www.cnblogs.com/wlx97e6/p/9550171.html

    HTTP GET请求的格式:

    HTTP响应的格式:

    定义自己的简易web框架

    import 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
    
    ")  # 包括响应行和响应头和换行
        conn.send(b"OK")  # 回复响应正文
        conn.close()
    

    此时在访问127.0.0.1:8000即可得到OK界面

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

    如何让我们的Web服务根据用户请求的URL不同而返回不同的内容呢?

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

    这样即可实现根据不同的url返回不同的界面

    让网页动态起来

    这网页能够显示出来了,但是都是静态的啊。页面的内容都不会变化的,我想要的是动态网站。

    没问题,我也有办法解决。我选择使用字符串替换来实现这个需求。(这里使用时间戳来模拟动态的数据)

    """
    根据URL中不同的路径返回不同的内容--函数进阶版
    返回HTML页面
    让网页动态起来
    """
    
    import socket
    import time
    
    sk = socket.socket()
    sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口
    sk.listen()  # 监听
    
    
    # 将返回不同的内容部分封装成函数
    def index(request):
        with open("index.html", "r", encoding="utf8") as f:
            s = f.read()
            now = str(time.time())
            s = s.replace("@@oo@@", now)  # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号
        return bytes(s, encoding="utf8")
    
    
    def home(request):
        with open("home.html", "r", encoding="utf8") as f:
            s = f.read()
        return bytes(s, encoding="utf8")
    
    
    # 定义一个url和实际要执行的函数的对应关系
    list1 = [
        ("/index/", index),
        ("/home/", home),
    ]
    
    while 1:
        # 等待连接
        conn, add = sk.accept()
        data = conn.recv(8096)  # 接收客户端发来的消息
        # 从data中取到路径
        data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串
        # 按
    分割
        data1 = data.split("
    ")[0]
        url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径
        conn.send(b'HTTP/1.1 200 OK
    
    ')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行
        # 根据不同的路径返回不同内容
        func = None  # 定义一个保存将要执行的函数名的变量
        for i in list1:
            if i[0] == url:
                func = i[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(性能比wsgiref好)、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref(本质是socket服务器),Django开发环境用的就是这个模块来做服务器,Werkuzeug也是实现了wsgi的模块(flask使用),下面wsgi左右的都是服务器,不过各自的功能不同,具体功能看下面的abc

    web框架本质和Python中 Web框架的分类

    web框架的本质:
    socket服务端 与 浏览器的通信

    socket服务端功能划分:
    a. 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn...
    b. 根据用户访问不同的路径执行不同的函数
    c. 从HTML读取出内容,并且完成字符串的替换 --> jinja2(模板语言)

    Python中 Web框架的分类:

    按上面三个功能划分:

    1. 框架自带a,b,c --> Tornado
    2. 框架自带b和c,使用第三方的a --> Django  第三方的a是wsgiref
    3. 框架自带b,使用第三方的a和c --> Flask  第三方的a是Werkzeug,c是jinja2

    按另一个维度来划分:

    1. Django --> 大而全(你做一个网站能用到的它都有)
    2. 其他 --> Flask 轻量级

    Django框架简介

    MVC框架和MTV框架

    MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等优点。

    Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。

    Django框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架。

    Django的MTV模式

           Model(模型):负责业务对象与数据库的对象(ORM)

           Template(模版):负责如何把页面展示给用户

           View(视图):负责业务逻辑,并在适当的时候调用Model和Template

    此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

    Django框架图示

    完整的简易请求流程

    0. 启动服务端,等待客户端(用户的浏览器)来连接
    1. 在浏览器地址栏输入URL,与服务端建立连接,浏览器发送请求
    2. 服务端收到请求消息,解析请求消息,根据路径和函数的对应关系,找到将要执行的函数
    3. 执行函数,打开HTML文件,进行字符串替换,得到一个最终要返回的HTML内容
    4. 按照HTTP协议的消息格式要求,把HTML内容回复给用户浏览器(发送响应)
    5. 浏览器收到响应的消息之后,按照HTML的规则渲染页面.
    6. 关闭连接

    Django的安装和启动

    安装(安装最新LTS版)

    LTS为官方长期维护的版本:

    这里有1.11版本的官方翻译文档,我看的时候官方翻译的文档没有1.11版本的,只有2.0及以后的,若看2.0以后,直接去官方看即可

    1.11的中文文档  还有 2.0的官方文档

    运行下面指令安装完成即可使用django-admin命令查看

    pip3 install django==1.11.11

    执行完成会在当前目录下安装django

    创建一个django项目

    (一)命令行创建方式(不推荐使用)

         1. cd到你要保存Django项目的目录
         2. Django-admin startproject 项目名   --> 会在当前目录创建Django项目

    django-admin startproject mysite
    # 若Django未加入到环境变量,可以到目录下找django文件 H:pythonvenvsMydjangoScriptsdjango-admin startproject newdjango

    (二)pycharm中创建django项目

      1.首先你要有一个安装了django的python解释器(没有的话pycharm一般也会帮忙创建,自动调用pip命令安装django,个别版本会有问题)

        1.如果是安装的纯净的解释器(官网直接下的):cd到解释器安装目录下Script目录的位置(里面有pip.exe的那个),然后执行pip3 install django==1.11.11,这时你就有一个安装了django的python解释器

        2.如果是pycharm中创建的虚拟环境,直接在虚拟环境的带有python.exe的同级目录下执行pip3 install django==1.11.11

        3.如果是别的虚拟环境。。。。。我也不会

      2.然后点击新建项目(选择安装了django的python解释器

    然后就可以了,测试是否创建成功就在项目里执行一下,然后点击控制台的链接,然后就可以看到祝贺界面

    也可以在命令行界面启动,保证自己保持和manage.py在同一目录下,然后执行 

    python manage.py runserver

    你应该会看到如下输出:

    Performing system checks...
    
    System check identified no issues (0 silenced).
    
    You have unapplied migrations; your app may not work properly until they are applied.
    Run 'python manage.py migrate' to apply them.
    
    十月 23, 2018 - 15:50:53
    Django version 2.1, using settings 'mysite.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.

    然后点击控制台的链接,然后就可以看到祝贺界面

    启动Django报错:

    Django启动:

    Django项目在pycharm中启动时,不要运行单个文件,要点击绿色三角运行

    命令行启动

    在项目的根目录下(也就是有manage.py的那个目录),运行:

    python3 manage.py runserver IP:端口--> 在指定的IP和端口启动
    python3 manage.py runserver 端口 --> 在指定的端口启动
    python3 manage.py runserver --> 默认在本机的8000端口启动

    Django 启动时报错 “UnicodeEncodeError ...”

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

    Django 启动报错“SyntaxError: Generator expression must be parenthesized”

    报这个错很大可能是因为使用了Python3.7.0,而目前(2018-06-12)Python3.7.0和Django还有点兼容性问题,换回Python3.6的环境即可。

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

    目录简单介绍

    1、外层总目录介绍

    在执行完    django-admin startproject mysite   的创建

    mysite/  # 项目根目录
    ├── manage.py  # 管理文件,互交命令行工具
    └── mysite  # 项目目录(纯Python包)
        ├── __init__.py  # Python包必带
        ├── settings.py  # 配置
        ├── urls.py  # 路由 --> URL和函数(类)的对应关系
        └── wsgi.py  # runserver命令就使用wsgiref模块做简单的web server

    这些文件是:

    • 外层的mysite/根目录仅仅是项目的一个容器。 它的名字与Django无关;可以将其重命名为你喜欢的任何内容。
    • manage.py:一个命令行工具,可以使你用多种方式对Django项目进行交互。 你可以在django-admin和manage.py中读到关于manage.py的所有细节。
    • 内层的mysite/目录是你的项目的真正的Python包。 它是你导入任何东西时将需要使用的Python包的名字(例如 mysite.urls)。
    • mysite/__init__.py:一个空文件,它告诉Python这个目录应该被看做一个Python包。 如果你是Python初学者,请在官方Python文档中阅读关于python包的更多内容
    • mysite/settings.py:该Django 项目的设置/配置。 Django settings 将告诉你这些设置如何工作。
    • mysite/urls.py:此Django项目的URL声明;Django驱动的网站的“目录”。 你可以在URL dispatcher 中阅读到更多关于URL的内容。
    • mysite/wsgi.py:用于你的项目的与WSGI兼容的Web服务器入口。 更多细节请参见如何使用WSGI部署

     2、APP层目录介绍

    应用和项目的区别:

    项目和应用之间有什么不同? 应用是一个Web应用程序,它完成具体的事项 —— 比如一个博客系统、一个存储公共档案的数据库或者一个简单的投票应用。 一个项目是特定网站的配置和应用程序的集合。 一个项目可以包含多个应用。 一个应用可以运用到多个项目中去。

    要创建你的应用,请确保与manage.py在同一目录中,并键入以下命令:

    python manage.py startapp polls
    

      这将创建一个目录polls,它的结构如下:

    polls/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py
    

           1、migrations目录:此目录记录了数据库变化情况

           2、admin.py文件: Django 为我们提供的后台管理

           3、apps.py文件:配置当前app

           4、models.py文件:此文件用来定义数据库表,ORM,写指定的类,通过命令可以创建数据库结构

           5、tests.py文件:此文件用于单元测试

           6、urls.py文件:此文件是APP自己的路由规则所在的文件(上面目录没有,是二级路由时用,可手动创建)

           7、views.py文件:此文件是视图函数的代码所在文件,关于视图函数会在后面的博客中详细介绍

     3、静态文件目录

    创建工程完成后,我们需要在工程根目录下创建一个“static”目录用户保存静态文件。

    关于静态文件,在网站中,那些图片、css、js等一般情况下内容不会变化的文件都是静态文件,我们可以把这些文件都放这个静态文件目录中。

    静态目录创建完成后需要在settings.py文件中添加如下的配置:

    STATIC_URL = '/static/'
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )
    

    4、模板文件目录

      模板文件就是指那些html文件,在用户访问的过程中,Django会将页面上的数据套用到模板文件,渲染成一个完整的字符串然后返回给客户端,这些模板文件存放在templates目录中,关于模板文件以及模板语言的语法将会在后续的博客中详细介绍。

    总目录https://www.cnblogs.com/wlx97e6/p/9143284.html

  • 相关阅读:
    20155238 2016-2017-2 《JAVA程序设计》第七周学习总结
    20155238 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
    20155238 2016-2017-2 《Java程序设计》第六周学习总结
    20155238 2016-2017-2 《Java程序设计》第五周学习总结
    20155238 2016-2017-2 《Java程序设计》第四周学习总结
    20155238 2016-2017-2 《Java程序设计》第三周学习总结
    20155238 2016-2017-2 《Java程序设计》第二周学习总结
    20155238 2016-2017-2 《Java程序设计》第一周学习总结
    第三次作业
    预备作业:有关技能以及“做中学”
  • 原文地址:https://www.cnblogs.com/wlx97e6/p/9556217.html
Copyright © 2011-2022 走看看