首页 > 其他分享 >初识Django

初识Django

时间:2022-12-08 22:56:58浏览次数:38  
标签:请求 py request django 初识 dict user Django

初识Django

前言:

本章主要是对web框架做一个基础了解,为了接下来学习前端框架做铺垫

必备知识点:

  • 什么是路由
    路由简单的来说就是根据用户请求的 URL 链接来判断对应的处理程序,并返回处理结果,也就是 URL 与 Django 的视图建立映射关系。

Django 路由在 urls.py 配置,urls.py 中的每一条配置对应相应的处理方法。路由简单的来说就是根据用户请求的 URL 链接来判断对应的处理程序,并返回处理结果,也就是 URL 与 Django 的视图建立映射关系。

Django 路由在 urls.py 配置,urls.py 中的每一条配置对应相应的处理方法。

  • 前端请求方式
    GET,表示向服务器获取资源
    POST,表示向服务器提交信息,通常用于产生新的数据,比如注册
    PUT,表示希望修改服务器的数据,通常用于修改
    DELETE,表示希望删除服务器的数据
    OPTIONS,发生在跨域的预检请求中,表示客户端向服务器申请跨域提交
    TRACE,回显服务器收到的请求,主要用于测试和诊断
    CONNECT,用于建立连接管道,通常在代理场景中使用,网页中很少用到GET,表示向服务器获取资源
    POST,表示向服务器提交信息,通常用于产生新的数据,比如注册
    PUT,表示希望修改服务器的数据,通常用于修改
    DELETE,表示希望删除服务器的数据
    OPTIONS,发生在跨域的预检请求中,表示客户端向服务器申请跨域提交
    TRACE,回显服务器收到的请求,主要用于测试和诊断
    CONNECT,用于建立连接管道,通常在代理场景中使用,网页中很少用到

GET和POST的区别

从 http 协议的角度来说,GET 和 POST 它们都只是请求行中的第一个单词,除了语义不同,其实没有本质的区别。
之所以在实际开发中会产生各种区别,主要是因为浏览器的默认行为造成的。
受浏览器的影响,在实际开发中,GET 和 POST 有以下区别:

  1. 浏览器在发送 GET 请求时,不会附带请求体
  2. GET 请求的传递信息量有限,适合传递少量数据;POST 请求的传递信息量是没有限制的,适合传输大量数据。
  3. GET 请求只能传递 ASCII 数据,遇到非 ASCII 数据需要进行编码;POST 请求没有限制
  4. 大部分 GET 请求传递的数据都附带在 path 参数中,能够通过分享地址完整的重现页面,但同时也暴露了数据,若有敏感数据传递,不应该使用 GET 请求,至少不应该放到 path 中
  5. 刷新页面时,若当前的页面是通过 POST 请求得到的,则浏览器会提示用户是否重新提交。若是 GET 请求得到的页面则没有提示。
  6. GET 请求的地址可以被保存为浏览器书签,POST 不可以
  • 纯手撸web框架

在写代码之前需要先了解web框架的本质是什么?

  1. 本质上web框架就是将前端与后端串联起来的一个中间介质,这是代码实现web的本质
  2. 框架的本质就好像是房子的主体结构一样,规定了这个放在必须按照这个规格建造,而框架也是如此

在写web框架之前需要先理一下如何写web框架的思路,思路如下

  1. 编写Socket服务端代码
    服务端代码在返回信息时需要使用http协议返回
  2. 根据URL路由获取不同的页面内容
    获取用户输入的后缀>>>: 请求数据信息GET信息
    3.处理请求数据获取路由
# 文件 socket_server.py
import socket

server = socket.socket()  # TCP
server.bind(('127.0.0.1', 8888))  # IP PORT
server.listen(5)  # 半连接池

while True:
    sock, address = server.accept()  # 等待链接
    data = sock.recv(1024)  # 字节(bytes)
    sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
    data_str = data.decode('utf8')  # 先转换成字符串
    target_url = data_str.split(' ')[1]  # 按照空格切割得到路由
    if target_url == '/index':
        with open(r'index.html', 'rb') as f:
            sock.send(f.read())
    elif target_url == '/login':
        sock.send(b'login page')
    else:
        sock.send(b'home page!')

  • 基于wsgire模块

wsgiref模块其实就是将整个请求信息给封装了起来,就不需要你自己处理了,假如它将所有请求信息封装成了一个叫做request的对象,
那么你直接request.path就能获取到用户这次请求的路径,request.method就能获取到本次用户请求的请求方式(get还是post)等,

"""
wsgire 是内置模块,现在很多主流的web框架都使用了这个模块
功能:
	1 . 封装了socket代码
	2. 处理请求数据
使用这个模块主要用来解决上面使用socket模块带来的一些问题
1. 固定代码启动服务端
2. 查看处理之后的request字典分析数据
3. 根据不同的路由返回不同的内容:根据request返回的数据处理
4. 针对于上述的 1 3 问题使用下列代码处理

"""
def run(request, response):
    """
    :param request:  请求相关数据,是有模块处理好的大字典信息
    :param response: 响应相关的数据
    :return:   返回给客户端的真实数据
    """
    response('200 OK', [])  # 固定格式
    path_info = request.get('PATH_INFO')  # 请求头的信息
    if path_info == '/index':
        return [b'index']
    elif path_info == '/login':
        return [b'login']
    return [b'hello wsgiref module']

if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)  # 实时监听服务端运行的端口,一旦有请求过来自动给第三个参数加括号传参并调用
    server.serve_forever()  # 启动服务端def run(request, response):


通过上述代码我们解决了 1 和 3 的问题也就是固定启动服务端,也可以得到request处理之后的大字典,关于最后我们需要对代码做优化和封装继续向下看

  • 代码封装优化

为什么需要优化

  1. 路由匹配问题:如果路由很多如何匹配?代码重复率过高
  2. 匹配成功后执行的代码或页面有多有少,如何处理?
上面说了为什么要优化代码,以及上面代码带来的问题,接下来考虑如何优化
  1. 使用函数封装和模块拆分的方式拆分代码
  2. 将分支代码封装为一个一个的函数
  3. 将路由和函数名做对应关系
  4. 获取路由循环匹配

根据上述优化完成之后,向增加新的功能只需要添加对应函数和对应关系即可
文件的拆分:

views.py   # 对应核心业务逻辑(功能函数)
urls.py  # 存储路由和功能函数的存储关系
templates目录  # 为了防止html文件太多太乱,创建相应的文件夹存放

代码优化的准备工作已经可以了 ,接下来在优化代码之前,需要先了解一下什么是动静态网页和jinja2模版的语法和使用

  • 动静态网页

简单来说静态页面就是与后端无交互,动态就是有交互,在优化时就需要将静态返回做为动态返回

  1. 静态网页:
    静态网页
    一般是编写好不会改变的,或者改变会从新编写的,数据来源是编写时就已经确定了,比如说宣传中的海报,请求方式为GET获取
  2. 动态网页:
    在编写时数据来源并不固定,一般指的的来源于数据库,比如说网页上的登录时间展示等,需要向后端提交一定的信息,请求方式一般为POST
  • jinja2模版语法与使用
    这里是 Jinja2 通用模板语言的文档。 Jinja2 在其是一个 Python 2.4 库之前,被设计 为是灵活、快速和安全的这里是 Jinja2 通用模板语言的文档。 Jinja2 在其是一个 Python 2.4 库之前,被设计 为是灵活、快速和安全的
    jinja2 在使用时可以处理接收的字典信息,并且可以使用句垫符,中括号,以及get的方式取值

代码优化

# 使用文件分离和jinja2对代码进行优化

1. 服务端代码 socket_server.py
from wsgiref.simple_server import make_server
from views import *
from urls import urls

def run(request, response):
    """
    :param request:  请求相关数据,是有模块处理好的大字典信息
    :param response: 响应相关的数据
    :return:   返回给客户端的真实数据
    """
    response('200 OK', [])  # 固定格式
    path_info = request.get('PATH_INFO')  # 请求头的信息
    func_name = None  # 定义一个用于后续存储用户函数名的变量
    for url_tuple in urls:  # 函数名
        if path_info == url_tuple[0]:
            func_name = url_tuple[1]
            break  # 匹配成功后无需再向后匹配
    if func_name:
        res = func_name(request)
    else:
        res = error_func(request)
    return [res.encode('utf8')]


if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)  # 实时监听服务端运行的端口,一旦有请求过来自动给第三个参数加括号传参并调用
    server.serve_forever()  # 启动服务端


2. views.py
from jinja2 import Template


def get_dict(request):
    user_dict = {'name': 'jason', 'age': 18, 'person_list': ['阿珍', '阿强', '阿香', '阿红']}
    with open(r'templates/get_dict_page.html', 'r', encoding='utf8') as f:
        date = f.read()
    temp_obj = Template(date)  # 将页面数据使用模版处理
    res = temp_obj.render({'user_dict': user_dict})  # 给页面传了一个 变量名是user_dict值是字典数据的数据
    return res


def error_func(request):
    return 'not a page'


def index(request):
    return 'hello index'


def login(request):
    return 'hello login'from jinja2 import Template


3. urls.py
from views import *
urls = [
    ('/index', index),
    ('/login', login),
    ('/get_dict', get_dict)
]

4. get_dict_page.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>{{ user_dict }}</p>
<p>{{  user_dict.name }}</p>
<p>{{ user_dict['age'] }}</p>
<p>{{ user_dict.get('person_list') }}</p>
</body>
  • 前端后端数据库联动

将数据库中的表以表格的形式在web前端展示

 数据表及数据
mysql> desc userinfo;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32) | YES  |     | NULL    |                |
| age   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

mysql> select * from userinfo;
+----+-----------+-----+
| id | name      | age |
+----+-----------+-----+
|  1 | xiaocheng |  38 |
|  2 | wesley    |  18 |
|  3 | xiaowang  |  28 |
|  4 | wesleyaaa |  18 |
|  5 | wang      |  28 |
|  6 | wesley55  |  18 |
+----+-----------+-----+
6 rows in set (0.01 sec)


------------------------------联动代码----------------------
目录文件:
├── index.html
├── socket_server.py
├── templates
│   └── get_dict_page.html
├── urls.py
└── views.py

-----------socket_server.py-----------------------------
from wsgiref.simple_server import make_server
from views import *
from urls import urls

def run(request, response):
    """
    :param request:  请求相关数据,是有模块处理好的大字典信息
    :param response: 响应相关的数据
    :return:   返回给客户端的真实数据
    """
    response('200 OK', [])  # 固定格式
    path_info = request.get('PATH_INFO')  # 请求头的信息
    func_name = None  # 定义一个用于后续存储用户函数名的变量
    for url_tuple in urls:  # 函数名
        if path_info == url_tuple[0]:
            func_name = url_tuple[1]
            break  # 匹配成功后无需再向后匹配
    if func_name:
        res = func_name(request)
    else:
        res = error_func(request)
    return [res.encode('utf8')]


if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)  # 实时监听服务端运行的端口,一旦有请求过来自动给第三个参数加括号传参并调用
    server.serve_forever()  # 启动服务端





----------------------templates/get_dict_page.html----------------------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
</head>
<body>

<div class="container"></div>
    <div class="row">
        <h1 class="text-center">数据展示</h1>
            <a href="/index">点击跳转index</a>
                <div class="col-md-8 col-md-offset-2">
                    <table class="table table-hover table-striped">
                        <thead>
                            <tr>
                                <th>id</th>
                                <th>name</th>
                                <th>age</th>
                            </tr>
                        </thead>
                        <tbody>
<!--                        [{}{}{}]-->
                        {% for user_dict in user_data_list %}
                            <tr>
                                <td>{{ user_dict.id }}</td>
                                <td>{{ user_dict.name }}</td>
                                <td>{{ user_dict.age }}</td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>

    </div>
</body>
</html>

-----------------views.py--------------------
import pymysql

def get_user(request):
    conn = pymysql.connect(
        user='root',
        password='Videojet2029@',
        host='121.4.86.62',
        port=3306,
        db='django',
        charset='utf8',
        autocommit=True
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select * from userinfo;"
    cursor.execute(sql)
    user_data = cursor.fetchall()
    print(user_data)
    # 读取数据
    with open(r'templates/get_dict_page.html', 'r', encoding='utf8') as f:
        data = f.read()
    temp_obj = Template(data)
    res = temp_obj.render({'user_data_list': user_data})
    return resimport pymysql

----------------urls---------------
from views import *
urls = [
    ('/index', index),
    ('/login', login),
    ('/get_dict', get_dict),
    ('/get_user', get_user)
]
  • web主流框架介绍
    1.django
    大而全 自身自带的功能组件非常的多 类似于航空母舰
    2.flask
    小而精 自身自带的功能组件非常的少 类似于游骑兵
    几乎所有的功能都需要依赖于第三方模块
    3.tornado
    异步非阻塞 速度极快效率极高甚至可以充当游戏服务端
    ps:sanic、fastapi...

  • django框架简介

注意事项
1.django项目中所有的文件名目录名不要出现中文
2.计算机名称尽量也不要出现中文
3.一个pycharm尽量就是一个完整的项目(不要嵌套 不要叠加)
4.不同版本的python解释器与不同版本的django可能会出现小问题

Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。
Django 是一个开放源代码的 Web 应用框架,由 Python 写成。
Django 遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0 。
Django 采用了 MVT 的软件设计模式,即模型(Model),视图(View)和模板(Template)

  • 名词解释
  1. 路由 用于判断用户需要请求页面的url后缀
  2. 函数 视图函数
  3. 视图类
  • djando中的重要层级
  1. urls.py 路由层
  2. views.py 视图层
  3. models.py 模型层
  4. templates 模版层
  • django基本操作命令
  1. 下载
pip3 install django  # 如果输入太慢可以使用 -i 参数临时使用国内源
  1. 验证是否安装成功
 wesley@***** ⮀ ~ ⮀ django-admin
····
[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
····
  1. 常用指令
"""
1. 创建django项目
django-admin startproject [projectname]
2. 启动项目
cd projectname && python3 manage.py runserver ip:port
3. 创建app
python3 manage.py startapp [appname]
注意:使用命令新创建的app应用需要注册
创建的app一定要去settings.py中注册
	INSTALLED_APPS = [
    	'app01.apps.App01Config',  # 写法一
		'app02'  # 写法二
	]

使用Pycharm创建项目的注意事项
1. 会自动创建templates文件夹,配置文件中可能会报错
更改/符号为:os.path.join(BASE_DRT, 'templates')
"""
  • django app 概念
    django整体就类似是一所大学,app类似于大学中的各个学院,每个都是独立的
    django里面的app类似于某个具体的功能模块
    user app 所有的用户相关的都写在user app下
    goods app 所有的商品相关的都卸载goods app下

  • django主要目录结构

 wesley@wesley ⮀ ~/PycharmProjects/django_test ⮀ tree -L 3
.
├── django_test  # django 项目名
│   ├── __init__.py  # 包文件
│   ├── settings.py  # 配置文件
│   ├── urls.py  #  路由文件
│   └── wsgi.py  # wsgiref网关文件
├── manage.py  # 入口文件
└── templates  # 存储html文件

django  项目目录名
django  项目同名目录
	settings.py		 配置文件
    urls.py			存储网址后缀与函数名对应关系(不严谨)
   	wsgi.py			wsgiref网关文件
	db.sqlite3文件	   django自带的小型数据库(项目启动之后才会出现)
	manage.py			 入口文件(命令提供)
应用目录
    migrations目录 存储数据库相关记录
    admin.py  django内置的admin后台管理功能
    apps.py			注册app相关
   	models.py		 与数据库打交道的(非常重要)
    tests.py		 测试文件
    views.py		 存储功能函数(不严谨)
   	templates目录			存储html文件(命令行不会自动创建 pycharm会)
    配置文件中还需要配置路径
    [os.path.join(BASE_DIR,'templates'),]
  • diango小白必会三板斧
# 需要导入模块
from django.shortcuts import render, HttpResponse, redirect
HttpResponse  # 返回字符串类型的数据
render  # 返回html页面并支持传值
redirect  # 重定向

标签:请求,py,request,django,初识,dict,user,Django
From: https://www.cnblogs.com/wesleyUP/p/16967663.html

相关文章

  • django框架
    web框架的本质理解1:连接前端与数据库的中间介质 理解2:socket服务端纯手撸web框架1.搭建socket服务端importsocketserver=socket.socket()server.bind(('127......
  • Django前戏手撸框架,Django入门,Django小白必会三板斧
    目录Django前戏手撸框架,Django入门,Django小白必会三板斧今日内容概要今日内容详细纯手撸web框架基于wsgiref模块代码封装优化动静态网页jinja2模块前端,后端,数据库三者联动p......
  • Django(一)
    Django(一)目录Django(一)纯手撸web框架基于wsgiref模块代码封装优化服务端代码urls代码view代码jinja2模块前端、后端、数据库三者联动python主流web框架django简介django基......
  • django框架——简介、基本使用、django app的概念、主要目录结构、“三板斧”
    django框架——简介、基本使用、djangoapp的概念、主要目录结构、“三板斧”一、django简介1.版本问题django1.X:同步 1.11django2.X:同步 2.2......
  • Django简介
    目录Django一、试写web框架1.web框架的本质2.自写web框架3.手写web框架的缺点二、基于wsgiref模块写web框架0.简介1.wsgiref模块的内容2.wsgiref的python代码3.代码封装优......
  • Django简介及安装、配置
    Django简介及安装、配置python主流web框架Django:特点是大而全这个特点意味着它功能的强大,也意味着它资源的臃肿,但是总体上还是瑕不掩瑜的一个框架。flask:特点是小而精......
  • Django框架
    今日内容概要纯手撸web框架基于wsgiref模块代码封装优化动静态网页jinjia2模板语法python主流web框架django框架简介django基本操作命令django小白必会三板斧......
  • django基础01
    纯手撸web框架1.web框架的本质 理解1:连接前端与数据库的中间介质理解2:socket服务端2.手写web框架 1.编写socket服务端代码2.浏览器访问响应无效>>>:HTTP协......
  • django框架 1
    今日内容详细纯手撸web框架1.web框架的本质 理解1:连接前端与数据库的中间介质 理解2:socket服务端2.手写web框架 1.编写socket服务端代码 2.浏览器访问响应无效>>>......
  • django
    目录django纯手撸web框架成功手写框架问题基于wsgiref模块代码封装优化动静态网页jinja2模块前端、后端、数据库三者联动python主流web框架django简介django基本使用django......