IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Django入门到放弃 学习笔记 01 -> 正文阅读

[Python知识库]Django入门到放弃 学习笔记 01

跟b站武沛齐老师的视频学习
对学习过程进行一些记录以便复习 同时自我督促 :D冲鸭

视频链接: 15天django入门到放弃-哔哩哔哩.

回顾

对数据库的操作:pymysql、SQLAlchemy、navicat(终端)

  1. 安装

  2. 创建用户 + 授权

  3. 连接

     - 数据库
     	终端创建数据库(字符编码) 
     - 数据表
     	终端、ORM、pymysql 
     	pymysql:create ...(数据类型/是否可以为空/主键/自增/外键/索引)engine=innodb支持事务性操作
     - 数据行 
     	增、删、改、查
     	查:limit、group by、order by ...
    

    关闭

内容概要

Web框架

  • socket
  • http协议
    连接方式对比
    HTTP:无状态、短连接
    TCP:不断开
  • HTML知识
  • 数据库(pymysql、SQLAlchemy)

Web应用

  • 浏览器(socket客户端)
    ② www.cnblogs.com(42.121.252.58,80)

     sk.socket()
     sk.connect((42.121.252.58,80)
     sk.send('我想要xx')
    

    ⑤ 接受
    ⑥ 连接断开

  • 博客园(socket服务端)
    ① 监听ip和端口(42.121.252.58,80)
    while True:
    – 用户 = 等待用户连接
    – ③ 收到‘我想要xx’
    – ④ 相应:“好”
    用户断开

铺垫练习

s1 简单的byte传输

简单的数据传输。

# -*- coding: utf-8 -*-
import socket


server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
server_socket.bind(('127.0.0.1', 8000))
server_socket.listen(5)

while True:
    client_socket, client_addr = server_socket.accept()  # 阻塞
    data = client_socket.recv(8096)  # 最大接收字节
    response = "HTTP/1.1 200 OK\r\n\r\n"  # 200 表示找到这个资源
    client_socket.send(response.encode('utf8'))
    client_socket.send(b'123123')
    client_socket.send(bytes("hello", encoding='utf-8'))
    client_socket.close()

s2 URL

对接收数据进行分割,提取出URL内容,实现不同URL页面显示不同文字。

# -*- coding: utf-8 -*-
import socket


server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
server_socket.bind(('127.0.0.1', 8000))
server_socket.listen(5)

while True:
    client_socket, client_addr = server_socket.accept()  # 阻塞
    data = client_socket.recv(8096)  # 最大接收字节
    data = str(data, encoding='utf-8')  # 想转成什么就写什么
    headers, bodys = data.split('\r\n\r\n')
    temp_list = headers.split('\r\n')
    method, url, protocal = temp_list[0].split(' ')

    response = "HTTP/1.1 200 OK\r\n\r\n"  # 200 表示找到这个资源
    client_socket.send(response.encode('utf8'))

    if url == "/xxxx":
        client_socket.send(b'123123')
    else:
        client_socket.send(b'404 not found')

    client_socket.close()

s3 静态网站

在s2基础上,将文件作为data返回,实现更复杂的数据传输。
s3.python

# -*- coding: utf-8 -*-
import socket


def f1():
    """
    处理用户请求,并返回相应的内容
    :param request: 用户请求的所有信息
    :return:
    """
    f = open('index.html', 'rb')
    data = f.read()
    f.close()
    return data


def f2():
    f = open('article.html', 'rb')
    data = f.read()
    f.close()
    return data


def f3():
    return b'word'


routers = [
    ('/index', f1),
    ('/article', f2),
    ('/word', f3)
]


def run():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    server_socket.bind(('127.0.0.1', 8000))
    server_socket.listen(5)

    while True:
        client_socket, client_addr = server_socket.accept()  # 阻塞
        data = client_socket.recv(8096)  # 最大接收字节
        data = str(data, encoding='utf-8')  # 想转成什么就写什么
        headers, bodys = data.split('\r\n\r\n')
        temp_list = headers.split('\r\n')
        method, url, protocal = temp_list[0].split(' ')

        response_header = "HTTP/1.1 200 OK\r\n\r\n"  # 200 表示找到这个资源

        func_name = None
        for item in routers:
            if item[0] == url:
                func_name = item[1]
                break

        if func_name:
            response_body = func_name()
        else:
            response_body = b'404'

        client_socket.send(response_header.encode('utf8'))
        client_socket.send(response_body)
        client_socket.close()

if __name__ == '__main__':
    run()

article.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>article</title>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>用户名</th>
                <th>邮箱</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th>1</th>
                <th>root</th>
                <th>root@qq.com</th>
            </tr>
        </tbody>
    </table>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
    <h1>用户登录</h1>
    <form>
        <p><input type="text" placeholder="用户名" /></p>
        <p><input type="password" placeholder="密码" /></p>
    </form>
</body>
</html>

s4 动态网站

修改了 s3.py 中函数 f2()f3(),实现时间的显示和数据库内容的读取。

def f2():
    f = open('time.html', 'r', encoding='utf-8')
    data = f.read()
    f.close()
    import time
    ctime = time.asctime(time.localtime(time.time()))
    data = data.replace('@@time@@', str(ctime))
    return bytes(data, encoding='utf-8')


def f3():
    import pymysql

    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='db_test')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 游标设置为字典类型

    cursor.execute("select id, username, password from userinfo")
    user_list = cursor.fetchall()

    conn.commit()
    cursor.close()
    conn.close()
    print(user_list)

    """
    要替换html文件中的@@content@
    将数据库中读取的数据改写为格式如:
    <tr>
        <th>id</th>
        <th>username</th>
        <th>password</th>
    </tr>
    """
    content_list = ""
    for row in user_list:
        tp = "<tr><td>%s</td><td>%s</td><td>%s</td></tr>" %(row['id'], row['username'], row['password'])
        content_list += tp
    content = "".join(content_list)

    f = open('userlist.html', 'r', encoding='utf-8')
    template = f.read()
    f.close()

    data = template.replace('@@content@@', content)
    return bytes(data, encoding='utf-8')

time.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>article</title>
</head>
<body>
    <h1>@@time@@</h1>
</body>
</html>

userlist.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>article</title>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>用户名</th>
                <th>密码</th>
            </tr>
        </thead>
        <tbody>
            @@content@@
        </tbody>
    </table>
</body>
</html>

过渡性总结

自己写网站

  • a. socket服务端
  • b. 根据URL不同返回不同的内容
    路由系统:URL -> 函数
  • c. 字符串返回给用户
    模板引擎渲染:HTML充当模板(特殊字符)、自己创造任意数据

Web框架

框架种类:

  • abc
    Tornado
  • [第三方a]+bc
    Django (应用python中wsgiref模块)
  • [第三方ac]+b
    flask(wsgiref、jinja2)

分类:

  • Django
  • 其他(轻量级框架)

Django入门

创建项目

基本指令:
安装:pip3 install django

django-admin startproject mysite
若没有添加环境变量,要在路径下执行。

其他常用命令:

python manage.py runserver ip:port (启动服务器,默认ip和端口为http://127.0.0.1:8000/)
python manage.py startapp appname (新建 app)
python manage.py syncdb (同步数据库命令,Django 1.7及以上版本需要用以下的命令)
python manage.py makemigrations (显示并记录所有数据的改动)
python manage.py migrate (将改动更新到数据库)
python manage.py createsuperuser (创建超级管理员)
python manage.py dbshell (数据库命令行)
python manage.py (查看命令列表)

项目建立完成得到如下文件夹:

mysite
├─── manage.py # 运行
└─── mysite
┈ ┈ ┈ ┈├─── __init__.py
┈ ┈ ┈ ┈├─── settings.py # 基本配置
┈ ┈ ┈ ┈├─── urls.py # 路由系统 url -> 函数
┈ ┈ ┈ ┈└─── wsgi.py # Web服务器网关接口 调用wsgiref模块 实现socket

基础配置

urls.py 文件中,urlpatterns 列表中增加路径;
引入 HttpResponse 模块,login 函数的返回值以此形式传递;
引入 HttpResponse 模块,可以读取其他文件,如 login.html 作为返回值。

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

from django.shortcuts import HttpResponse, render

def login(request):
    """
    处理用户请求,并返回内容
    :param request: 用户请求相关的所有信息(对象)
    :return:
    """
    # return HttpResponse('login')
    # 自动找到模板路径下的login.html文件,读取内容并返回给用户
    return render(request, 'login.html')


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

寻找文件的路径依据,在 settings.pyTEMPLATES 里进行了定义:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ...

templates 文件夹中的 login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
    <h1 style="color: cadetblue">用户登录</h1>
    <form>
        <p><input type="text" placeholder="用户名" /></p>
        <p><input type="password" placeholder="密码" /></p>
        <p><input type="submit" value="登录"></p>
    </form>
</body>
</html>

运行可看到页面:

也可以将样式写入CSS文件中,修改 login.html,加入样式链接:

<link rel="stylesheet" href="/sta/commons.css">

sta 文件夹下新建 commons.css 文件:

h1{
    color: cadetblue;
}

运行发现样式未应用,检查报错,发现CSS文件未能被找到;

原因是静态文件路径需要配置,在 setting.py 中最后修改静态路径:

STATIC_URL = '/static/' # 使用时前缀 /static
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'sta'),
)

修改 login.html 中的链接:

<link rel="stylesheet" href="/static/commons.css">

再运行时,样式应用成功。

*将 sta 文件夹直接命名未 static 更加和谐统一,日后将所有静态文件放在 static 目录下。
(静态文件:图片、JS、CSS)

完善登录功能

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link rel="stylesheet" href="/static/commons.css">
</head>
<body>
    <h1>用户登录</h1>
    <form method="post" action="/login/">
        <p><input type="text" placeholder="用户名" name="username"/></p>
        <p><input type="password" placeholder="密码" name="password"/></p>
        <p><input type="submit" value="登录"></p>
        {{ msg }}
    </form>
</body>
</html>

这里用户端返回的消息形式:<QueryDict: {'username': ['root'], 'password': ['123123']}>
urls.py

def login(request):
    """
    处理用户请求,并返回内容
    :param request: 用户请求相关的所有信息(对象)
    :return:
    """
    # return HttpResponse('login')
    # 自动找到模板路径下的login.html文件,读取内容并返回给用户
    if request.method == "GET":
        return render(request, 'login.html', {'msg': '请输入用户名和密码'})
    else:
        # 用户POST提交的数据(请求体)
        """
        usr = request.POST['username']
        psw = request.POST['password']
        这样的方式并不好,取决于html文件中的name,如果不匹配会报错
        """
        usr = request.POST.get('username')
        psw = request.POST.get('password')
        if usr == 'bernie' and psw == '123456':
            # 登录成功
            return redirect('http://www.baidu.com')
        else:
            # 登录失败
            return render(request, 'login.html', {'msg': '用户名或密码错误'})

首次访问,请求形式为 GET,将登录界面返回给用户;用户输入用户名和密码后,请求形式为 POST,则进行判断,登录成功则借助 redirect 重定位跳转到指定网址;否则重新将登录界面返回给用户,并给出错误提示信息。

总结

1. 创建project

2. 配置

模板路径 - templates目录
静态文件路径 - static目录

3. 额外配置

MIDDLEWARE'django.middleware.csrf.CsrfViewMiddleware', 注释掉

4. url对应关系

/login/ login

def login(request):

– request.method
– request.POST ->请求体
– request.GET ->请求头中的url中
(GET请求:只有request.GET有值;POST请求:request.GET和request.POST都可能有值)

– return HttpResponse(…)
– return render(request, ‘login.html’, {…})
– return redirect(‘要跳转的网址’或’/后缀/’)

5. 模板引擎的特殊标记

login.html
{{name}}

def login(request):
return render(request, ‘login.html’, {‘name’: ‘alex’})

html文件中的引用:

<p>{{ name }}</p>
<p>{{ users.0 }}</p>
<p>{{ users.1 }}</p>
<p>{{ user_dict.k1 }}</p>
<p>{{ user_dict.k2 }}</p>
<h3>循环</h3>
<ul>
{% for item in users %}
	<li> {{ item }} </li>
{% endfor %}
</ul>
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:29:59  更:2021-08-22 13:30:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:27:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码