第五十五天 django框架基础之一

一、手搓web框架

1.socket服务端代码
2.HTTP协议   四大特性   数据格式   响应状态码!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3.根据网址后缀的不同请求不同的内容
4.请求方式
GET
	朝服务端索要数据
POST
	朝服务端提交数据
import socket


server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)


while True:
    sock, address = server.accept()
    data = sock.recv(1024)
    # 因为是流式协议,可以把头先进行发送,之后再发送后面if种的东西
    sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
    target_url = data.decode('utf8').split(' ')[1]
    if target_url == '/index':
        sock.send(b'index view')
    elif target_url == '/login':
        sock.send(b'login view')
    elif target_url == '/reg':
        sock.send(b'reg view')
    else:
        sock.send(b'404 error')

5.从请求数据格式中筛选出用户输入的网址后缀
	target_url = data.decode('utf8').split(' ')[1]
6.代码的缺陷
	1.socket代码重复编写造轮子
	2.针对请求数据格式的处理复杂且重复
 	3.针对不同网址后缀的匹配方式过于lowB
7.注意前面注释中的-因为是流式协议,可以把头先进行发送,之后再发送后面if种的东西

二、基于wsgiref模块撸

wsgiref内部封装了socket代码和对请求数据的处理

from wsgiref.simple_server import make_server


def run(request, response):
    """
    :param request: 请求数据
    :param response: 响应数据
    :return: 返回给客户端的数据
    """
    print(request)  # 自动将请求数据全部处理成字典k:v键值对形式
    response('200 OK', [])  # 固定代码 无需掌握
    return [b'hello big baby']


if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)  # 任何访问127.0.0.1:8080的请求都会给第三个参数加括号调用
    server.serve_forever()  # 永久启动

1.wsgiref模块解决了两个问题
	1.socket代码重复编写造轮子
	2.针对请求数据格式的处理复杂且重复

三、基于wsgiref进行代码封装优化

from wsgiref.simple_server import make_server


def run(request, response):
    """
    :param request: 请求数据
    :param response: 响应数据
    :return: 返回给客户端的数据
    """
    response('200 OK, []')
    target_path = request.get('PATH_INFO')
    if target_path == '/index':
        return [b'index']
    elif target_path == '/login':
        return [b'login']
    else:
        return [b'404']


if __name__ == '__main__':
    #  run的位置也可以是个对象
    server = make_server('127.0.0.1', 8000, run)
    server.serve_forever()

2.思考如何再次实现根据不同的网址后缀返回不同的内容(函数化)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
先从大字典中查找出记录网址后缀的键值对
	1.不推荐使用连续的多个if判断
	2.针对面条版的代码首先应该考虑封装成函数


利用多文件的函数封装来进行代码优化
具体文件在day22就不写出来了

四、动静态网页

动态网页
	页面上的数据不是全部写死的 有些是动态获取(后端传入)
静态网页
	页面上的数据直接写死的 要想改变只能修改源码

实际需求
	后端代码回去当前时间 然后让前端页面展示
	1.字符串替换
 	2.将字典数据传递给html页面并且想要在页面上操作字典数据
    	我们无法自己实现>>>:在html页面上使用类似于后端的语法操作数据

def get_time(request):
    import time
    current_time = time.strftime('%Y-%m-%d %H:%M:%S')
    with open('templates/myhtml02.html', 'r', encoding='utf8') as f:
        data = f.read()
    data.replace('hahaha', data)
    return data

五、jinjia2模块

jinja2能够让我们在html文件内使用类似于后端的语法来操作各种数据类型
pip3 install jinja2


from jinja2 import Template
def get_dict(request):
    user_dict = {'name': 'jason', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
    with open(r'templates/myhtml04.html','r',encoding='utf8') as f:
        data = f.read()
    temp = Template(data)
    res = temp.render(data=user_dict)  # 将字典传递给html页面 页面上通过data即可获取(data仅仅是一个变量名)
    return res

**<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
    <h1>{{ data }}</h1>
    <h1>{{ data['name'] }}</h1>
    <h1>{{ data.get('pwd') }}</h1>
    <h1>{{ data.hobby }}</h1>
</body>
</html>**
这里Template的写法可能会有一点歧义,下面的那个会更加清晰一点

mac 版本的mysql安装以及添加环境变量

终端输入open .bash_profile
如果没有.bash_profile文件就自己创建一个
注意.bash_profile里面原来的东西别乱动
在文件中添加export PATH="$PATH":/usr/local/mysql/bin   保存
之后在终端输入source .bash_profile
现在重启终端依旧会消失
打开文件open .zshrc
在文件中输入source ~/.bash_profile
在命令端输入source .zshrc
就可以打开就使用mysql了
没有文件的情况下创建文件的指令   touch .文件名

六、前端、后端、数据库联动(render--提供的意思 execute--执行)

def get_mysql(request):
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='sy123456',
        database='day55',
        charset='utf8',
        autocommit=True
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = 'select * from userinfo'
    cursor.execute(sql)
    user_data = cursor.fetchall()
    with open('templates/myhtml04.html', 'r', encoding='utf8') as f:
        data = f.read()
        temp = Template(data)
        res = temp.render(user_data=user_data)
        return res
# 这样就可以直接利用user_data去调用数据库中的内容了
# cursor是最关键的单词

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <h1 class="text_canter">数据展示</h1>
            <div class="col-md-6 col-offset-3">
                <table>
                    <thead>
                        <tr>
                            <th>主键</th>
                            <th>姓名</th>
                            <th>年龄</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for user in user_data %}
                        <tr>
                            <td>{{user.id}}</td>
                            <td>{{user.name}}</td>
                            <td>{{user.age}}</td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</body>
</html>
# {% for user in user_data %}的作用很大,能够让数据库在增删数据的同时网页也跟着变化!!!!!!!!!
# 注意这个代码的开始与结束,以及括号两边都需要加%,代码行只有一个{},数据获取行有两个{}

七、模板语法

<h1>{{ data }}</h1>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('pwd') }}</h1>
<h1>{{ data.hobby }}</h1> 

{% for user in user_data %}
    <tr>
        <td>{{ user.id }}</td>
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
    </tr>
{% endfor %}

八、python主流web框架

django框架
	大而全 自身携带的功能非常的多 类似于航空母舰
		缺陷:开发小项目的时候使用该框架有点笨重(大材小用)

flask框架
	小而精 自身携带的功能非常的少 类似于特种兵 主要依赖于第三方模块
    	缺陷:受限于第三方模块的开发

tornado框架
	异步非阻塞 该框架快到可以作为游戏服务器
    	缺陷:上手难度是三者最高的

fastapi框架、sanic框架、...
	最近流行的 抽空可以看看

"""
框架虽然多 但是内部逻辑大差不差 我们重点学习一个即可>>>:django
	如果你是小白切记不要同时学习上述框架
"""

九、django基本操作命令(这个面试很有可能会考)

命令行操作
	1.创建django项目
    	django-admin startproject 项目名
 	2.启动django项目
    	1.先切换到项目目录下
        	cd 项目名
       2.执行启动目录
    		 python38 manage.py runserver ip:port
 	3.访问django服务端
    	浏览器直接访问
 	4.创建app应用
    	"""
    	django框架类似于是一个空壳子 给你提供所需的资源
    	至于到底要写哪些功能 需要通过创建app来划分
    		eg:django初始项目可以看成是一所大学
    		   app就相当于是大学里面的各个学院
    	"""
       python38 manage.py startapp 应用名
    	

pycharm操作
	鼠标点点点即可

"""
在启动django项目的时候 一定要确保一个端口只有一个项目!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""

1.先创建一个项目
django_admin stratproject mysite
2.切换到项目名文件夹下
cd mysite
3.利用文件夹下的文件启动django项目(manage.py是项目中的文件)
python3.9 manage.py runserver
4.访问django服务端
浏览器直接访问
5.先退出访问
crtl+c
6.创建app应用
python3.9 manage.py startapp app01

image

要注意python的版本号得保持一致

image

mac知识点补充说明

1.mac系统的默认文件目录为
Users/用户名/路径文件
2.mac版本的终端停止服务
也是crtl+c

十、命令行与pycharm操作的区别

1.命令行不会自动创建templates文件夹
2.命令行不会在配置文件编写关于templates文件夹的配置
	'DIRS': [os.path.join(BASE_DIR, 'templates')]
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 下面这句话需要自己加上去
        'DIRS': [BASE_DIR,'templates'],
        # 最标准的写法
        'DIRS': [os.path.join(BASE_DIR,'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

3.pycharm自动创建的第一个应用会自动注册到配置文件中
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01'
]
# 注意每当自己创建一个app就必须给他写进去!!!!!!!!!!!!!!!!!!!!!!

4.针对db.sqlite3文件不用去在乎它有没有创建 只要运行了django会自动出来

十一、django目录结构

django项目目录

项目同名文件夹
	__init__.py  	很少用 主要做一些冷门配置
	settings.py    项目配置文件
	urls.py		   对应关系(目前简单的理解:网址后缀跟函数名)
	wsgi.py		  django服务 基本不用
	manage.py			 django入口文件
	templates文件夹		  存储项目所需的html文件
应用名文件夹(可以有多个)
	migrations文件夹  orm相关(数据库打交道的记录)
	__init__.py  	很少用 主要做一些冷门配置
	admin.py		 django自带的后台管理
	apps.py			创建应用之后用于应用的注册
	models.py		存储与数据库表相关的类
	tests.py			自带的测试文件
	views.py		 存储业务相关的逻辑代码(函数、类)
	db.sqlite3			 自带的小型数据库

urls.py		路由层
views.py	视图层
templates	模板层
models.py	模型层

image

十二、django小白必会三板斧

HttpResponse
	主要用于直接返回字符串类型的数据
render
	主要用于返回html页面 并且支持模板语法
redirect
	主要用于页面重定向



from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
    path('func/', views.func),
    path('login/', views.login)
]


from django.shortcuts import render, HttpResponse, redirect


# Create your views here.
def index(request):
    return HttpResponse('你好呀小宝贝')


def func(request):
    user_dict = {'name': 'jason', 'pwd': 123}
    return render(request, 'func.html', {'data': user_dict})


def login(request):
    # return redirect('https://www.baidu.com')
    return redirect('/index/')

最后提醒一下settings文件中加参数的时候类似于'DIRS': [os.path.join(BASE_DIR, 'templates')] 一定要加中括号!!!!!!!!!!

posted @ 2023-11-11 23:17  暧昧的花蝴蝶  阅读(16)  评论(0)    收藏  举报