Django框架入门前缀(手搭web框架)

建议在看这一章节前,先了解一下HTTP协议的组成:HTTP协议

前言:

在了解Django之前,我们可以先了解web框架,了解它的好处是什么呢?在一步步搭建它的过程中,我们会逐步明白到Django是如何写的,以及如果处理页面接收与反馈给页面数据的。当然 这样讲可能有点抽象,那么我们先来了解一下吧!

什么是web框架?

Web框架是用来进行Web应用开发的一个软件架构。主要用于动态网络开发。开发者在基于Web框架实现自己的业务逻辑。Web框架实现了很多功能,为实现业务逻辑提供了一套通用方法。

  • 简而言之:通过web框架可以实现在网络上访问我们的web应用

Python主流三大Web框架

1、DJango:重量级框架

Django是基于Python的免费和开放源代码Web框架,它遵循模型-模板-视图(MTV)体系结构模式。它封装的的功能常丰富且非常多所以它是重量级,Django的文档最完善、市场占有率最高、招聘职位最多。但如果需要实现的功能很少就会略显笨重

2、Flask:轻量级框架

Flask 是 Python 编写的一种轻量级 ( 微 ) 的 Web 开发框架,只提供 Web 框架的核心功能,较其他类型的框架更为的自由、灵活、更加适合高度定制化的 Web 项目。Flask 在功能上面没有欠缺,Flask的第三方开源组件比丰富,因此 Flask 对开发人员的水平有了一定的要求。使用Flask开发较依赖于第三方组件

3、Tornado:异步非阻塞框架

Tornado是一种 Web 服务器软件的开源版本。Tornado 和主流Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快,得利于其非阻塞的方式和对epoll的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。但很多功能都需要开发者自己去编写


1、搭建web服务端

这里的web服务端是我们使用socket套接字来实现的,以浏览器为客户端 朝我们搭建的服务端发送数据,以及我们的服务端给浏览器返回数据的过程。

import socket

server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 重用端口

server.bind(('127.0.0.1',8080)) # 绑定ip与端口,供浏览器访问


server.listen(5)

while True:
    conn, addr = server.accept() # 与访问的浏览器建立连接,进行数据接收与发送

    receive = conn.recv(1024) # 接收浏览器发送的请求

    print(receive) # 打印请求格式

    conn.send(b'HTTP1.1/ 200 ok \n\n') # 服务端已经处理了浏览器发送的请求,返回状态

    conn.send(b'Hello') # 响应浏览器一个Hello字符

此时我们打开浏览器:

在这里插入图片描述



2、使用wsgire模块

便于我们提取请求报文的内容,这里使用Python中一个更便于本次实验的模块:wsgiref

我们的代码只需要稍加变动,但效果还是和上面一致的。

from wsgiref.simple_server import make_server

def run(request,response): # 使用run函数来处理请求 以及响应数据,需要定义两个形参来接收请求。
    '''

    :param request:   客户端的请求数据
    :param response:  给客户端进行响应的数据
    :return:
    '''
    response('200 ok', []) # 返回响应状态给客户端

    print(request) # 打印请求报文

    return [b'World'] # 响应给客户端(浏览器)一个World字符


if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run) # 分别代表:ip、端口、由哪个程序来处理请求
    server.serve_forever() # 将服务器持续开启

在这里插入图片描述
用户的请求数据:打印出来是一个字典形式的

在这里插入图片描述

那么此时,我们在浏览器发送请求时,稍作变动。

比如:用户访问127.0.0.1:8080/index,那么页面要出现index字符我们该如何实现呢。

首先服务端需要获取url后面的/index,才能进行处理。那么我们来代码实现吧

from wsgiref.simple_server import make_server

def run(request,response): # 使用run函数来处理请求 以及响应数据,需要定义两个形参来接收请求。
    '''

    :param request:   客户端的请求数据
    :param response:  给客户端进行响应的数据
    :return:
    '''
    response('200 ok', []) # 返回响应状态给客户端

    # 获取ip+端口后面的内容,如:127.0.0.1:8080/index,我们就要获取/index
    current_path = request['PATH_INFO']
    # 一切用户请求的封装到了这个字典里面,而我们想要内容就在这个key里面

    if current_path == '/index':
        return [b'Index']

    return [b'404 Error']


if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run) # 分别代表:ip、端口、由哪个程序来处理请求
    server.serve_forever() # 将服务器持续开启

在这里插入图片描述
如果再访问其它页面,那么服务端就会返回404 Error了。

现在我们的功能要拓展了,比如:用户要访问Login页面,并且该页面还要一些代码来专门处理用户请求,以及返回给用户一些数据。

按照上面的思路是不是一个页面对应一个if?那岂不是一个文件堆满了if嘛,所以我们需要将用户访问、以及处理响应用户的步骤进行拆分了。



3、文件拆分实现

我们需要先建立一个文件夹,里面存放这三个文件。

urls:用于表示用户输入的url应哪一个函数

'''
    根据用户输入的url,返回该url对应的处理函数
'''

import views

url_handle = [  # 存放每个页面对应的处理函数
    ('/index',views.index),
    ('/login',views.login)
]

views:用于处理用户的请求与响应用户数据

'''
    接收用户请求、在对应函数可以进行一番处理然后响应给用户数据。
'''

def index(request): # 接收用户请求

    '''中间可以有处理过程'''

    return 'index' # 将数据返回给调用这个函数的变量

def login(requets): # 接收用户请求
    return 'login'

我们web框架的入口程序:

from wsgiref.simple_server import make_server
from urls import url_handle

def run(request,response): # 使用run函数来处理请求 以及响应数据,需要定义两个形参来接收请求。
    '''

    :param request:   客户端的请求数据
    :param response:  给客户端进行响应的数据
    :return:
    '''
    response('200 ok', []) # 返回响应状态给客户端

    # 获取ip+端口后面的内容,如:127.0.0.1:8080/index,我们就要获取/index
    current_path = request['PATH_INFO']
    # 一切用户请求的封装到了这个字典里面,而我们想要内容就在这个key里面

    judeg = False # 定义一个标识


    func = '' # 定义一个变量,用于接收处理用户请求的函数返回的数据

    for tuple_url in url_handle:
        # 判断用户输入的页面地址,是否则在我们定义的处理列表里面
        if current_path == tuple_url[0]:
            func = tuple_url[1](request) # 调用对应的处理函数,并且将用户的请求传递给它,然后接收函数处理好并返回的数据;
            judeg = True
            break

    if judeg:
        return [func.encode('utf-8')]

    return [b'404 Error'] # 上面判断失败,则说明用户输入的url不在我们定义的范围内,则返回404


if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run) # 分别代表:ip、端口、由哪个程序来处理请求
    server.serve_forever() # 将服务器持续开启

相信此时运行已经可以看到效果了,并且此后我们的入口文件再也不需要进行改动了。

如果需要再添加新的页面,那么我们只需要修改urls文件、与views文件。

  • views添加对应url的处理函数
  • urls添加url与处理函数绑定。


4、网页文件导入

我们返回给浏览器的可以是定义的字符串,也可以是HTML标签。我们创建一个HTML文件。

register.html

<!DOCTYPE html>
<html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>register</title>
      </head>
      <body>
        <h1>注册界面</h1>
      </body>
</html>

我们再views文件里面添加函数:

def register(request):
    with open('register.html','rt') as f:
        data = f.read()
    return data

urls文件也做出增加:

import views

url_handle = [
    ('/index',views.index),
    ('/login',views.login),
    ('/register',views.register)
]

那么我们再访问:http://127.0.0.1:8080/register就可以看到如下效果:
在这里插入图片描述
那么如何将我们的Python内容传递到页面,并且还支持取值操作呢?

那么就该今天的第二个主角登场了:jinja2模块



5、jinja2模块

jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。

它具备自己的语法结构,当我们按照它的语法结构定义,那么就可以向对应的位置传值了。

实例:

from jinja2 import Template

data = '''
    我是:{{ name }},今年:{{ age }}
'''

template = Template(data) # 先建立好一个模板

# 模板内可以接收name、age名称的数据,那么我们只需要使用:模板.render方法传入就可以
data = template.render({'name':'jack','age':18}) 

print(data)

打印结果:


    '我是:jack,今年:18'

那么此时就明白了jinja2的作用了吧,现在我们将HTML页面也定义这种数据格式,然后在Python内把HTML文件的内容读取出来,再使用jinja2处理一下返回给浏览器。

test.html

<!DOCTYPE html>
<html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>test.html</title>
      </head>
      <body>
        <h1>{{ test_data }}</h1>
      </body>
</html>

views.py

def test(request):
    with open('test.html','rt') as f:
        data = f.read()

    from jinja2 import Template

    template = Template(data)

    data = template.render(test_data='我是在Python内处理了,然后才进行导入的')

    return data

urls.py

'''
    根据用户输入的url,返回该url对应的处理函数
'''

import views


url_handle = [  # 存放每个页面对应的处理函数
    ('/index',views.index),
    ('/login',views.login),
    ('/register',views.register),
    ('/test',views.test)
]

打开浏览器查看效果:
在这里插入图片描述

jinja2还支持循环,并且取值方式和python几乎相同。在此之前,我们先将所有的html文件存放到一个tempelates的文件夹,因为随着html文件越来越多,显的会非常的乱。

此时我们的目录结构:
在这里插入图片描述
那么现在来尝试一下jinja2的循环存入值吧!


先在templates文件夹下创建一个user_info.html的文件:

这里我们使用了前端框架:bootstrap,主要就是笔者不想写样式和效果啦

<!DOCTYPE html>
<html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>user_info</title>
         <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.css" rel="stylesheet">
          <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
      </head>
      <body>
        <table class="table table-bordered table-hover table-striped text-center" style="width: 300px" align="center">
            <thead>
                <tr>
                    <td>Id</td>
                    <td>Name</td>
                    <td>Age</td>
                </tr>
            </thead>
            <tbody>
                {% for data in user_dic %}
                <tr>
                    <td>{{ data.id }}</td>
                    <td>{{ data.name }}</td>
                    <td>{{ data.age }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
      </body>
</html>

views.py

def user_info(request):
    with open('templates/user_info.html', 'rt') as f:
        data = f.read()

    template = Template(data)

    dic = [
        {'id':1,'name':'jack','age':18},
        {'id':2,'name':'tom','age':19},
        {'id':3,'name':'jams','age':23},
        {'id':4,'name':'rouse','age':21},
    ]

    data = template.render({'user_dic':dic})

    return data

urls.py

import views


url_handle = [  # 存放每个页面对应的处理函数
    ('/index',views.index),
    ('/login',views.login),
    ('/register',views.register),
    ('/test',views.test),
    ('/user_info',views.user_info)
]

此时打开页面的效果:
在这里插入图片描述

当然,也可根据自身需求导入数据库,都是可以的。并且我们修改HTML的内容,再次刷新页面也可以同步过来,因为我们本身就是一个文件,每次访问到url地址都会执行函数然后再次加载HTML文件,所以达到了一个同步的效果。

最终我们的程序目录:
在这里插入图片描述
我们会发现,main文件从我们创建了views、urls后,再也没有操作过一次了,只是使用它来运行而已。

到了这里其实在往后写,本质上和写Django的区别也不是很大了,只是少了很多Django自带的一些功能,那么我们本章节的内容就是以上这些了。


如果本文对您有帮助,别忘一键3连,您的支持就是笔者最大的鼓励,感谢阅读!

下一章节传送门:Django基础


技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点赞 收藏+关注 子夜期待您的关注,谢谢支持!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值