django数据库操作

Posted asdaa

tags:

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

一:web框架基础简介

【1】web框架本质

  (1)web本质也是C/S架构 

  (2)浏览器:客户端

  (2)服务端:服务端

 

【2】web框架自定义

技术图片
import socket
server = socket.socket()
server.bind((‘127.0.0.1‘,8080))
server.listen(6)


while True:
    conn ,addr = server.accept()
    # 字符串
    recv_data = conn.recv(1024).decode(‘utf-8‘)
    print(recv_data)
    conn.send(b‘hello world‘)
    conn.close()

技术图片

(1)客户端结果展示

技术图片

 

 

(2)服务端结果展示

技术图片
‘‘‘b‘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; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

‘‘‘
技术图片

PS:客户端无法正常接收数据的原因

(1)首先浏览器向服务端发送请求的时候 这个数据怎么发送 格式是什么样式

(2)不同的网站可能对发送方式定义的不一样 如果太多不一样 导致整个互联网紊乱

(3)因此我们使用同一标准HTTP协议

 

【3】HTTP协议版本

技术图片
import socket
server = socket.socket()
server.bind((‘127.0.0.1‘,8080))
server.listen(6)


while True:
    conn ,addr = server.accept()
    # 字符串
    recv_data = conn.recv(1024)
    # HTTP版本 响应状态码 换行符
    conn.send(b‘HTTP/1.1 200 OK

‘)
    conn.send(b‘hello world‘)
    conn.close()
技术图片

 

二:Web框架修正版

【1】根据用户请求的url不同返回相应的数据

(1)作用:每个用户可能请求的数据不同 根据用户请求的结果不同 返回不同的数据

(2)思路:

  (1)首先需要获取用户输入的路径

  (2)获取用户的路径根据不同的路径做不同从处理

例如:

技术图片
import socket

server = socket.socket()
server.bind((127.0.0.1, 8080))
server.listen(6)

while True:
    conn, addr = server.accept()
    # 拿到用户传入的数据 将其转为字符串状态
    recv_data = conn.recv(1024).decode(utf-8)
    print(recv_data)  # 字符串
    
    # 将获取的字符串进行切割获取列表
    path_list = recv_data.split(
)[0]
    
    # 列表取索引获取访问路径
    current_path = path_list.split( )[1]
    
    print(current_path)  # /index

    # 根据HTTP协议进行数据交互
    conn.send(bHTTP/1.1 200 OK

)

    # 根据访问路径不同 返回不同的结果
    if current_path == /index:
        conn.send(bindex)
    elif current_path == /home:
        conn.send(bhome)

    #     访问资源不存 返回404
    else:
        conn.send(b404 error)
根据路径不同获取不同的响应结果
技术图片
‘‘‘
D:Softwarespython3.6python.exe "E:/work station/day51/django基础版本.py"

请求首行
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; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: cross-site
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8




请求体:用户没传入

   # conn.send(b‘HTTP/1.1 200 OK 

‘)
服务端接受的字符串数据

【2】路由与视图函数对应关系

(1)作用:

  (1)上述代码解决了根据不同的url返回不同的结果

  (2)但是假如有多个条件语句 需要写大量的条件判断 这样肯定是不合理的

(2)解决办法

  (1)创建路由与函数的对应关系 通过路由来执行不同的功能

例如:

import socket

server = socket.socket()
server.bind((127.0.0.1, 8080))
server.listen(6)


def index(current_path):
    response = fhello{current_path}
    # 将字符串转换成二进制传输
    return bytes(response,encoding=utf-8)


def home(current_path):
    response = fhello{current_path}
    return bytes(response, encoding=utf-8)

# 创建路由与视图函数关系 以后添加新的功能 直接添加路由与对应的视图函数即可
url_list = [
    (/index, index),
    (/home, home)
]

while True:
    conn, addr = server.accept()
    # 拿到用户传入的数据 将其转为字符串状态
    recv_data = conn.recv(1024).decode(utf-8)

    # 将获取的字符串进行切割获取列表
    path_list = recv_data.split(
)[0]

    # 列表取索引获取访问路径
    current_path = path_list.split( )[1]

    # 根据HTTP协议进行数据交互
    conn.send(bHTTP/1.1 200 OK

)

    func = None
    #  循环打印上述路由与视图关系列表
    for url in url_list:
        # 如果用户的url路径在上述列表中
        if url[0] == current_path:
            # 给上述函数赋值
            func = url[1]
            # 函数赋值之后 不需要再继续进行循环 直接打印即可
            break
    # 如果上函数被赋值  则调用函数
    if func:
        res = func(current_path)
    else:
        res = b404 error

    # 返回消息给客户端
    conn.send(res)
    conn.close()

三:动静态网页传递

(1)定义:

  (1)静态网页:数据是固定不变的

  (2)动态网页:数据是是可灵活变化的

(2)作用:

  (1)在上述代码中我们返回一些无用的字符串呈现给用户

  (2)在网页传递过程中我们传递相应的HTML文件呈现给用户

例如:

import socket

server = socket.socket()
server.bind((127.0.0.1, 8080))
server.listen(60)


def index():
    # 对于python来说什么文件都是二进制 直接读取发送即可

    with open(rht1.html, rb) as file:
        data = file.read()
        return data


def home():
    with open(rht1.html, rb) as file:
        data = file.read()
        return data


url_dict = {
    /index: index,
    /home: home
}

while True:
    conn, addr = server.accept()
    recv_data = conn.recv(1024).decode(utf-8)
    url_list = recv_data.split(
)[0]
    url_path = url_list.split( )[1]

    conn.send(bHTTP/1.1 200 OK

)
    func = None
    for key, value in url_dict.items():
        if key == url_path:
            func = url_dict.get(key)
            break

    if func:
        res = func()

    else:
        res = b404 error

    conn.send(res)
    conn.close()
技术图片
import socket

server = socket.socket()
server.bind((127.0.0.1, 8080))
server.listen(66)
from datetime import datetime

func = None


def index():
    now_time = datetime.now().strftime(%Y-%m-%d %X)
    with open(rh2.html, r, encoding=utf-8) as f:
        data = f.read()

        # 读取HTML中的数据 将其替换成我们想要传给用户的数据 这样类似于我们将后端数据插入到HTML数据中
        time = data.replace(SR, now_time).encode(utf-8)
        return time


def home():
    now_time = datetime.now().strftime(%Y-%m-%d %X)
    with open(rh2.html, r, encoding=utf-8) as f:
        data = f.read()

        # 读取HTML中的数据 将其替换成我们想要传给用户的数据 这样类似于我们将后端数据插入到HTML数据中
        time = data.replace(SR, now_time).encode(utf-8)
        return time


url_list = {
    /index: index,
    /home: home
}

while True:
    conn, addr = server.accept()
    recv_data = conn.recv(1024).decode(utf-8)
    conn.send(bHTTP/1.1 200OK

)
    # 获取url地址
    url_path = recv_data.split(
)[0].split( )[1]

    for key, value in url_list.items():
        if key == url_path:
            func = url_list.get(key)
            break
    if func:
        res = func()
    else:
        res = b404 error

    conn.send(res)
    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开发环境用的就是这个模块来做服务器。

 

五:WSGI/jinja2基本使用方式

【1】wsgi

(1)作用:

  (1)可以利用该模块替换我们自己写的socket server部分

  (2)将客户端传入的数据拆封成字典

  (3)将服务端传入给客户端的数据封装携带含有HTTP协议

例如:

技术图片
# 导入模块
from wsgiref.simple_server import make_server


def index():
    data = bhello world!
    return data


def home():
    data = bhello world!
    return data


url_list = {
    /index: index,
    /home: home
}


def run_server(request, response):
    ‘‘‘
    与客户端进行数据交互的函数
    :param request: 用户请求数据
    :param response: 服务端回应数据
    :return:
    ‘‘‘
    print(request)  # 用户传来的数据自动变成字典格式
    response(200 ok, [])  # 回应客户端的格式

    url_path = request.get(PATH_INFO)
    func = None
    for key,value in url_list.items():
        if key == url_path:
            func = url_list.get(key)
            break
    if func:
        res = func()
    else:
        res = b404 error

    return [res]



if __name__ == __main__:
    # 监听该地址加上端口号 如果有请求 直接调用该函数
    server = make_server(127.0.0.1, 8080, run_server)
    # 启动服务端
    server.serve_forever()
wsgiref的使用方式

【2】jinja2与html结合

(1)作用:将后端传递给前端的数据进行页面渲染

例如:

技术图片
import pymysql
from jinja2 import Template
from wsgiref.simple_server import make_server



def mysql():
    conn = pymysql.connect(
        host=127.0.0.1,
        port=3306,
        user=root,
        password=123,
        database=day51,
        charset=utf8,
        autocommit=True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = "select * from user_info"
    affect_rows = cursor.execute(sql)
    data = cursor.fetchall()
    with open(rmy_sql.html,r,encoding=utf-8) as f:
        recv_data = f.read()
    temp = Template(recv_data)
    res = temp.render(user_list=data).encode(utf-8)
    return res


url_list = {
    /mysql: mysql,

}



def run(request, response):
    url_path = request[PATH_INFO]
    response(200 ok, [])
    func = None
    for key, value in url_list.items():
        if key == url_path:
            func = url_list.get(key)
            break

    if func:

        res = func()
    else:
        res = b404 error

    return [res]


if __name__ == __main__:
    server = make_server(127.0.0.1, 8080, run)
    print(启动)
    server.serve_forever()
jinja2与数据库
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">

    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h2 class="text-center">用户数据展示</h2>
            <table class="table table-hover table-bordered table-striped">
                <thead>
                <tr>
                    <th class="text-center">id</th>
                    <th class="text-center">username</th>
                    <th class="text-center">age</th>
                </tr>
                </thead>
                <tbody>
                {%for user_dict in user_list%}
                <tr>
                    <td class="text-center">{{user_dict.id}}</td>
                    <td class="text-center">{{user_dict.name}}</td>
                    <td class="text-center">{{user_dict.age}}</td>
                </tr>
                {%endfor%}
                </tbody>
            </table>
        </div>

    </div>
</div>

</body>
</html>
前端

六:Django安装使用

【1】命令行安装启动

(1)Django安装

pip3 install django=1.11.11

(2)检查Django是否安装成功

Django-admin

(3)创建Django项目

Django-admin startproject + 项目名称

(4)Django目录介绍

技术图片
mysite/
├── manage.py  # 管理文件
└── mysite  # 项目目录
    ├── __init__.py
    ├── settings.py  # 配置
    ├── urls.py  # 路由 --> URL和函数的对应关系
    └── wsgi.py  # runserver命令就使用wsgiref模块做简单的web server
技术图片

(5)创建Django应用

django-admin startapp  + 应用名
python manage.py startapp +  应用名

(6)目录应用介绍

技术图片
└──  migrations     # 数据库迁移记录
    ├── admin.py    # 后台管理
    ├── apps.py     # 应用注册相关
    ├── models.py   # orm模型类
    └── test.py     # 测试文件
    └── views.py    # 视图函数
技术图片

(6)启动Django服务

Django-admin manage.py runserver

技术图片

 

 技术图片

 PS:

(1)命令行创建Django项目不会自动生成templates文件夹

(2)settings配置文件中也需要修改

(3)创建的项目需要在配置文件注册生效 否则无识别

 

七:Django基础三件套

from django.shortcuts import HttpResponse, render, redirect

(1)HttpResponse

作用:内部输入字符串 返回给浏览器

例如:

def index(request):
    # 业务逻辑代码
    return HttpResponse("hello world")

 

(2)render

作用:

(1)接受一个需要渲染的文件以及字典

(2)将数据填充进模板文件 返回给前端

例如:

def index(request):
    # 业务逻辑代码
    return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})

PS:其前端接受取值 只能通过.的方式进行取值

 

(3)redirect

作用:接受一个url地址 跳转到另外一个地址

例如:

def index(request):
    # 业务逻辑代码
    return redirect("/home/")

 

八:Web简易数据通讯过程

技术图片

 

以上是关于django数据库操作的主要内容,如果未能解决你的问题,请参考以下文章

django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段

Django REST框架--认证和权限

如何在 Django 中显式重置模板片段缓存?

使用 Django 模板作为片段

VSCode自定义代码片段——git命令操作一个完整流程

python 通过django片段很多很多