Django简介

Django


image-20211001230147585

一、试写web框架

1.web框架的本质

角度1:处于连接前端与数据库的中间部分

角度2:也可以理解为web框架的本质就是socket服务端

Django既可以和浏览器做交互,也可以从DB数据库拿数据

=>三层框架中的核心逻辑层或者是接口层

2.自写web框架

  • 步骤:

(1)用python编写socket服务端代码,通过浏览器来访问

(2)浏览器访问响应无效>>>自编写的socket服务端没有支持HTTP协议

image-20221208085249942

(3)支持HTTP协议后,又有新的问题

image-20221208171108963

如何根据不同的网址后缀,获取不同的网页内容

针对上述问题=>如何找到网站的后缀?

(4)想找到用户输入的后缀>>从请求数据中查找

image-20221208090033418

(5)详解请求首行

GET /index HTTP/1.1
请求首行 作用
GET请求 向服务端所要数据
POST请求 向服务端提交数据
  • GET请求

    image-20221208171841879
  • POST请求

image-20221208090333716

(6)处理请求数据获取网址后缀

import socket

server = socket.socket()  # tcp
server.bind(('127.0.0.1', 9090))  # 不经常改变的ip地址
server.listen(5)  # 半连接池

while True:
    sock, address = server.accept()  # 等待连接
    data = sock.recv(1024)  # recv 字节数bytes
    # print(data.decode('utf8'))  # 解码打印
    sock.send(b'HTTP/1.1 200 ok\r\n\r\n')
    data_str = data.decode('utf8')  # 转换成字符串
    target_url = data_str.split(' ')[1]
    # print(target_url) /reg /favicon.ico
    if target_url == '/reg':
        sock.send(b'reg page')
    elif target_url == '/login':
        sock.send(b'login page')
    else:
        sock.send(b'home page')

3.手写web框架的缺点

(1)socket代码过于重复

(2)针对请求数据处理繁琐

(3)后缀匹配逻辑很简单

二、基于wsgiref模块写web框架

0.简介

wsgiref是python的内置模块,很多web框架底层使用的模块

  • 功能:

    1.封装了socket代码

    2.对于请求数据已经做了很多处理,封装了很多方法

1.wsgiref模块的内容

1)固定代码启动服务端

(2)查看wsgiref模块处理之后的request大字典

(3)根据不同网址后缀 找到字典中的键值对

2.wsgiref的python代码

from wsgiref.simple_server import make_server


def run(request, response):
    """
    :param request: 请求相关数据
    :param response: 响应相关数据
    :return: 返回给客户端的真实数据
    """

    response('200 OK', [])  # 固定格式
    # print(request) 结果是wsgiref模块处理之后的一个大字典
    path_info = request.get('PATH_INFO')
    if path_info == '/index':
        return [b'index page']
        break  # 匹配成功,后续无序匹配直接结束
    elif path_info == '/reg':
        return [b'eg page']
    return [b'hello wsgiref module']


if __name__ == '__main__':
    server = make_server('127.0.0.1', 9080, run)
    server.serve_forever()  # 很重要,没有它启动不了服务器
  • 不同的web网页后缀,wsgiref模块会给客户端返回已经处理好了的信息,类似日志的模式
image-20221208094230436
  • 没写server.serve_forever()的情况,则会出现无法连接的情况

    image-20221208094317354

wsgiref模块已经优化了我们自己编写基于socket模块的问题:

1.socket代码过于重复

2.针对请求数据处理繁琐

3.代码封装优化

  • 通过wsgiref模块编写完客户端后,可优化的内容

1.网址后缀的匹配问题--

wsgiref模块中,请求数据已经被处理成了名为request的大致点,我们所要找到了后缀就在request这个大字典中的PATH_INFO

image-20221208184624017

2.每个后缀匹配成功后执行的代码

  • python中的代码的逻辑升级:

    面条版=>函数版=>模块=>多文件

3.将分支的代码封装成一个个函数

手写框架中,我们也可以做分割

image-20221208185740865

4.将网址后缀与函数名做对应关系

image-20221208185907645

5.获取urls.py中的对应关系,将获得的网址后缀循环匹配得到函数名

image-20221208190301851

6.如果想新增功能只需要在views.py中先写函数再添加新的函数名与后缀名的对应关系到urls.py中

7.根据软件开发目录拆分成不同的py文件和目录

py文件名 作用
wsgiref.py 存放核心业务逻辑和 路由匹配分发(网址后缀匹配)
urls.py 存放路由匹配的信息 后缀对应函数名
views.py 存放功能函数(业务函数)

8.最终使得函数体代码中业务逻辑具有更多的数据

img

三、动静态网页

1.什么是动静态网页

  • 动态网页:页面数据来源于后端
  • 静态网页:页面数据是固定的、不变的

xueweihan

2.动态网页

(1)需求1:(前后端传递字符串)访问某个网址后缀,后端代码获取当前时间,并将该时间传到html文件上再返回给浏览器展示给用户看

  • 解决思路:读取html内容(字符串类型) 然后利用字符串替换 最后再返回给浏览器

  • 步骤1:新增/login后缀名,编写login_func,并创建templates文件夹专门存放html文件

image-20221208191624346
  • 步骤2:通过字符串的replace替换方法,实现动态网页

def login_func(request):
    ctime = time.strftime('%Y-%m-%d %X')
    with open(r'template/get_str.html','r',encoding='utf8') as f:
        data = f.read()
    data = data.replace('asdfasddxfexfeza',ctime)
    return data
image-20221208192333660

(2)需求2:(前后端传递dict字典类型的数据)将字典传递给页面内容,并且在页面上还可以通过类似于后端的操作方式操作该数据

模板语法>>>:jinja2模块

from jinja2 import Template


def get_dict_func(request):
    user_dict = {'name': 'duoduo', 'age': 123, 'hobbies': ['read', 'sing songs', 'lol']}
    with open(r'template/get_dict.html', 'r', encoding='utf8') as f:
        data = f.read()
    # 获取jinja2模块中的templates类所产生的对象
    tem_obj = Template(data)  # 通过Template模版中的方法去处理HTML页面上的数据
    res = tem_obj.render({"d1": user_dict})  # 给页面传递一个字典template.render({'knights': 'that say nih'})
    return res
  • html文件中使用模版语法
<body>
    <p>{{d1}}</p>
    <p>{{d1.name}}</p>
    <p>{{d1['age']}}</p>
    <p>{{d1.get('hobbies')}}</p>
</body>

在页面/dict中会显示出来字典中的数据,通过jinja2模版语法实现

image-20221208200916150

四、jinja2模板语法

1.jinja2模板的作用

将后端的数据塞进前端页面上

2.template类中render方法的作用

image-20221208194513451

五、前端、后端、数据库交互

需求:前端浏览器访问get_user,后端连接数据库查询user表中所有的数据,传递到某个html页面,弄弄好样式,再发送给浏览器展示

  • 数据库MySQL中准备数据
# 创建库
create database day51;
# 切换库
use day51;
# 创建表
create table get_user(id int primary key auto_increment,name varchar(32),age int );
# 插入数据
insert into get_user(name,age) values('duoduo',13),('lucy',12),('cici',33);
  • views.py

通过pymysql模块连接数据库,获得数据库中的数据,再通过再html页面中填写jinja2模版语法,在后端文件views.py中用jinja2中的Template中的方法处理数据,在返回展示在web页面

import jinja2
import pymysql


def get_db(request):
    conn = pymysql.Connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        passwd='root123',
        db='day51',
        autocommit=True,
        charset='utf8'
    )
    # 产生游标对象,并指定返回数据是[{}]
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql1 = "select * from get_user;"
    cursor.execute(sql1)
    user_dict = cursor.fetchall()
    # print(user_dict)
    # [{'id': 1, 'name': 'duoduo', 'age': 13}, {'id': 2, 'name': 'lucy', 'age': 12}, {'id': 3, 'name': 'cici', 'age': 33}]
    with open(r'template/get_db.html', 'r', encoding='utf8') as f:
        data = f.read()
    temp_obj = Template(data)  # 通过jinja2模版语法操作html页面
    res = temp_obj.render({'user_dict': user_dict})
    return res
  • get-db.html
<body>
<div class="container">
    <div class="row">
        <h1 class="text-center">一个数据库展示的页面</h1>
        <div class="col-md-8 col-md-offset-2">
            <table class="table table-hover table-bordered table-condensed table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>名字</th>
                    <th>年龄</th>
                </tr>
                </thead>
                <tbody>
                {% for user_info in user_dict %}
                <tr>
                    <td class="active">{{user_info.id}}</td>
                    <td class="success">{{user_info['name']}}</td>
                    <td class="danger">{{user_info.get('age')}}</td>
                </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
image-20221208210407244

六、python主流web框架

1.那么什么是web框架呢?

Web应用框架有助于减轻网页开发时共通性活动的工作负荷,例如许多框架提供数据库访问接口、标准样板以及会话管理等,可提升代码的可再用性。

说简单点就是web框架用于搭建Web应用程序,免去不同Web应用相同代码部分的重复

2.主流框架简介

主流框架 特点
Django 大而全,自身自带的功能组件非常的多,类似于航空母舰
flask 小而精,自身自带的功能组件非常的少,类似于游骑兵
几乎所有的功能都需要依赖于第三方模块
tornado 能实现异步非阻塞,速度极快效率极高甚至可以充当游戏服务端

七、Django简介

image-20211118141522986

1.MVT与MVC

Django 采用了 MVT 的软件设计模式,即模型(Model),视图(View)和模板(Template)

(1)MVC架构 - 主流的web框架

image-20221208211245467

这个MVT模式并非django首创,在其他的语言里面也有类似的设计模式MVC,甚至可以说django里面的MVT事实上是借鉴了MVC模式衍生出来的。

M,Model,模型,是用于完成操作数据库的。

V,View,视图,里面的代码就是用于展示给客户端的页面效果。

C,Controller,控制器,是一个类或者函数,里面的代码就是用于项目功能逻辑的,一般用于调用模型来获取数据,获取到的数据通过调用视图文件返回给客户端。

(2)MVT架构 - Django的框架

image-20221208211401810

  1. M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
  2. V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
  3. T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。

MVT模型的工作流程

image-20221208211441505

路由控制器将请求转发给对应的视图函数,完成业务逻辑,视图函数将从model中获取的数据嵌入到template的中模板文件(html)渲染成一个页面字符串,返回给客户端的流程。

所以我们学习Django重点是四个部分:url路由器+MVT

2.Django中的版本问题

版本 特点 LTS版本号 上线时间 Python版本
django1.X 同步 1.11 2017.04 2.7、3.4、3.5、3.6、3.7 (added in 1.11.17)
django2.X 同步 2.2 2019.4 3.5、3.6、3.7、3.8(在 2.2.8 中添加)、3.9(在 2.2.17 中添加)
django3.X 支持异步 3.2 2021.4 3.6、3.7、3.8、3.9、3.10(在 3.2.9 中添加)
django4.X 支持异步 4.1最新版 2023.4 3.9、3.10

img

3.使用Django的注意事项

  1. 计算机名称不要出现中文

  2. python解释器版本不同可能会出现启动报错

  3. 项目中所有的文件名称不要出现中文

  4. 多个项目文件尽量不要嵌套,做到一个Django项目一个文件夹启动一个pycharm窗口

  • 启动如果报错,根据提示找到修改widgets.py文件第152行源码,删除最后的逗号即可
img

八、Django基本使用

1.终端中命令

  • 下载Django-2.2

    豆瓣源

pip install django==3.2 -i https://pypi.douban.com/simple/
  • 查看Django版本
python -m django --version
  • 创建django项目
django-admin startproject Djangoproject
  • 切换到django项目目录
cd Djangoproject
  • 创建app
 python3 manage.py startapp app01
  • 运行django项目
python3 manage.py runserver 127.0.0.1:8001
image-20221208164842341
  • 可以打开pycharm 打开Django项目,已经创建了app01目录
image-20221208165347670
  • 还需要在settings.py中进行注册
image-20221208165806925
  • pycharm自动创建django项目

pycharm会自动创建templates文件夹,但是配置文件没有添加templates文件夹的路径,会报错

只需要添加代码即可:

os.path.join(BASE_DIR,'templates')

image-20221208213811895

九、Django主要目录结构

1.Django主要目录结构

└─ django项目同名目录
    │─ settings.py    # 默认开发配置文件
    │─ urls.py        # 路由列表目录,用于绑定视图和url的映射关系
    │─ wsgi.py        # wsgiref网关为难,wsgi就是项目运行在wsgi服务器时的入口文件
    └- __init__.py
│─ manage.py        # 入口文件,终端脚本命令,提供了一系列用于生成文件或者目录的命令,也叫脚手架
│─ temples目录       # 存储html文件(命令行不会自动创建 pycharm会)
│─ db.sqlite3文件    # django自带的小型数据库(项目启动之后才会出现)
└─ 应用目录app01
    │─ migrations目录   # 存储数据库相关记录 
    │─ admin.py        # django内置的admin后台管理功能
    │─ apps.py         # 注册app相关,该应用的一些配置,自动生成
    │─ models.py       # 模型层,该应用的模型类模块
    │─ tests.py        # 该应用的单元测试模块
    │─ views.py        # 该应用的视图模块,存储功能函数

2.名词解释

nickname 专业名词
网址后缀 路由
views.py中的函数 视图函数
views.py中的类 视图类
urls.py 路由层
views.py 视图层
models.py 模型层
templates 模板层

十、Django中app的概念

1.app是什么

Django中的app是某个具体的功能模块

  • user用户相关的功能,放在user_app中

2.创建app

  • 命令行创建应用
python3 manage.py startapp app名称 
  • python中创建应用
1.新建Django项目的时候,可以新建一个app
	-新建的app会自动帮忙在settings中注册

2.自己创建app
settings中添加
'app01.apps.App01Config'
或者'app01'

十一、Django中的三大方法

1.三大方法

  • 导入模块
from django.shortcuts import render,HttpResponse,redirect
方法名 作用
HttpResponse 返回字符串类型的数据
render 返回html页面并且支持传值
redirect 重定向

2.HttpResponse

#  HTTPResponse方法 返回字符串
def index_func(request):
    return HttpResponse('HttpResponse返回字符串类型数据')

image-20221209002404793

3.render

render(request: Any, template_name: Any,模版中html文件名 context: Any = None)上下文

import pymysql

# render方法 返回html页面并支持传旨
def login_func(request):
    # 连接mysql数据库,获得数据库中的数据
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        passwd='root123',
        db='day51',
        autocommit=True,
        charset='utf8'
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql1 = "select * from get_user;"
    cursor.execute(sql1)
    data_dict = cursor.fetchall()
    # 将mysql中的数据通过jinja2 在页面上展示
    return render(request, 'login_page.html', {'user_dict': data_dict})
  • templates目录中的html文件

    Django中也有模版语法,与jinja2不同的是:Django的模版语法只支持点的方式获取值

 <div class="row">
        <h1 class="text-center">一个数据库展示的页面</h1>
        <div class="col-md-8 col-md-offset-2">
            <table class="table table-hover table-bordered table-condensed table-bordered">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>名字</th>
                    <th>年龄</th>
                </tr>
                </thead>
                <tbody>
                {% for user_info in user_dict %}
                <tr>
                    <td class="active">{{user_info.id}}</td>
                    <td class="success">{{user_info.name}}</td>
                    <td class="danger">{{user_info.age}}</td>
                </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
image-20221209003818258

4.redirect

redirect的参数是一个网页或者是路由

def src_func(request):
    return redirect('https://www.baidu.com')
    return redirect('/index/')
posted @ 2022-12-08 22:06  Duosg  阅读(580)  评论(0编辑  收藏  举报