first commit
BIN
project1/.DS_Store
vendored
Normal file
229
project1/01.Python环境部署.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# Python介绍
|
||||
|
||||
> Life is short, I need python(人生苦短,我用python!)
|
||||
|
||||
## Python起源
|
||||
|
||||
Python的作者是著名的"**龟叔**"Guido van Rossum(吉多.范罗苏姆),1989年,龟叔为了打发无聊的圣诞节,决心开发一个新的**解释程序**,作为ABC语言的一种继承。于是便开始编写Python语言。
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902103540169.png" alt="image-20240902103540169" style="zoom: 80%;" />
|
||||
|
||||
**ABC**是由吉多参加设计的一种教学语言,就吉多本人看来,ABC这种语言非常优美和强大,是**专门为非专业程序员设计的**。但是ABC语言并没有成功。**Guido**本人看来,**ABC**失败的原因是高级语言为时过早,并且平台迁移能力弱,难以添加新功能,仅仅专注于编程初学者,没有把有经验的编程人员纳入其中,在**Python**中解决了这些问题,让拓展模块的编写非常容易,并且可以在多平台进行运行....
|
||||
|
||||
Python的意思是蟒蛇,是取自英国20世纪70年代首播的电视喜剧《蒙提.派森干的飞行马戏团》(Monty Python’s Flying Circus),Guido非常喜欢这个剧,所以选择Python作为新语言的名字。
|
||||
|
||||
**1991年**,第一个Python编译器诞生。它是用C语言实现的,并能够调用C语言的库文件。
|
||||
|
||||
## 解释型和编译型语言
|
||||
|
||||
解释型语言是指在运行时由解释器逐行读取和执行源代码的语言。在这种语言中,代码不需要被提前编译成机器代码,而是直接由解释器逐行解析并执行。这使得开发过程更加灵活,程序员可以快速测试和修改代码。Python、JavaScript 和 Ruby 等都是常见的解释型语言。尽管解释型语言在开发时提供了便利,但由于逐行解释执行,通常在性能上不如编译型语言。
|
||||
|
||||
编译型语言则是指在执行之前,源代码需要通过编译器转换成机器代码或中间代码。这个过程通常会产生一个独立的可执行文件,运行时不再需要源代码或编译器。这种做法通常能提高程序的执行效率,因为编译后的代码可以直接在机器上运行。C、C++ 和 Go 等语言都是编译型语言。虽然编译型语言在执行速度上表现出色,但编译过程通常较长,调试和修改代码时也不如解释型语言方便
|
||||
|
||||
## 编程语言排行
|
||||
|
||||
- [TIOBE Index](https://www.tiobe.com/tiobe-index/)
|
||||
- [PYPL Index](https://pypl.github.io/PYPL.html)
|
||||
|
||||
<img src="./01.Python环境部署/image-20240920215125704.png" alt="image-20240920215125704" style="zoom:80%;" />
|
||||
|
||||
## Python应用领域
|
||||
|
||||
**人工智能**
|
||||
|
||||
Python 是人工智能和机器学习领域的首选语言,主要得益于其简洁的语法和丰富的科学计算库。以下是几种典型的 Python 库:
|
||||
|
||||
- **NumPy**:支持大量的维度数组与矩阵运算,此外也针对数组运算提供了大量的数学函数库。
|
||||
- **SciPy**:基于 NumPy 的科学计算库,提供了许多算法和函数,适用于数值积分与优化、线性代数、统计等科学计算任务。
|
||||
- **Matplotlib**:强大的绘图库,可以生成各种图形,包括线图、散点图、柱状图等,常用于数据可视化。
|
||||
- **TensorFlow**:由 Google 开发的开源深度学习框架,广泛用于构建和训练神经网络。
|
||||
|
||||
**云计算**
|
||||
|
||||
Python 是云计算领域最火的语言之一,广泛用于构建和管理云基础设施。Python 的简洁性和可读性使得它成为开发云服务、自动化任务、数据处理脚本的理想选择。
|
||||
|
||||
**WEB开发**
|
||||
|
||||
Python 拥有众多优秀的 Web 框架,适合快速开发高效、安全的 Web 应用程序。许多大型网站和服务都是用 Python 开发的,例如 YouTube、Dropbox、豆瓣等。以下是几种典型的 Web 框架:
|
||||
|
||||
- **Django**:一个高层次的 Python Web 框架,鼓励快速开发和简洁、实用的设计,是全栈框架的代表。
|
||||
- **Flask**:一个轻量级的 Web 框架,强调简单性和灵活性,适合构建小型项目或微服务。
|
||||
|
||||
**系统运维**
|
||||
|
||||
Python 是系统运维人员的必备语言。它可以用于编写脚本来自动化任务、管理服务器、处理文件和文本、与操作系统进行交互等。Python 的跨平台性使得它在不同的操作系统上都能有效发挥作用。
|
||||
|
||||
**金融**
|
||||
|
||||
Python 在金融领域特别是量化交易和金融分析方面得到广泛应用。Python 的灵活性和丰富的金融数据分析库,使得它在金融工程领域的使用日益增多,重要性逐年提高。
|
||||
|
||||
**图形界面开发 (GUI)**
|
||||
|
||||
Python 也可以用于开发桌面应用程序,以下是几种常用的图形界面开发库:
|
||||
|
||||
- **PyQt**:基于 Qt 框架的 Python 绑定,适合开发复杂的桌面应用程序。
|
||||
- **WxPython**:基于 wxWidgets 的 Python GUI 库,提供了跨平台的原生控件。
|
||||
- **TkInter**:Python 的标准 GUI 库,适合初学者和轻量级应用的快速开发。
|
||||
|
||||
## Python实际应用
|
||||
|
||||
**谷歌**:Google App Engine、code.google.com、Google Earth、谷歌爬虫、Google 广告等项目都在大量使用 Python 开发。
|
||||
|
||||
**CIA**:美国中情局网站就是用 Python 开发的。
|
||||
|
||||
**NASA**:美国航天局(NASA)大量使用 Python 进行数据分析和运算。
|
||||
|
||||
**YouTube**:世界上最大的视频网站 YouTube 就是用 Python 开发的。
|
||||
|
||||
**Dropbox**:美国最大的在线云存储网站,全部用 Python 实现,每天网站处理 10 亿个文件的上传和下载。
|
||||
|
||||
**Instagram**:美国最大的图片分享社交网站,每天超过 3000 万张照片被分享,全部用 Python 开发的。
|
||||
|
||||
**Facebook**:大量的基础库均通过 Python 实现的。
|
||||
|
||||
**Redhat**:世界上最流行的 Linux 发行版本中的 yum 包管理工具就是用 Python 开发的。
|
||||
|
||||
**豆瓣**:公司几乎所有的业务均是通过 Python 开发的。
|
||||
|
||||
**知乎**:国内最大的问答社区,通过 Python 开发(国外 Quora)。
|
||||
|
||||
除上面之外,还有搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝、土豆、新浪、果壳等公司都在使用 Python 完成各种各样的任务
|
||||
|
||||
## Python设计哲学
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902110217569.png" alt="image-20240902110217569" style="zoom:80%;" />
|
||||
|
||||
Python 的设计哲学与其他编程语言相比,有几个显著的不同之处:
|
||||
|
||||
1. **可读性优先**:
|
||||
- Python 强调代码的可读性,力求清晰明了。这与如 C++ 或 Java 等语言相比,后者往往更关注性能或复杂的语法结构。
|
||||
2. **简洁性**:
|
||||
- Python 鼓励用较少的代码实现功能,通常会有简化的语法,而像 Java 这样的语言则要求更多的样板代码。
|
||||
3. **动态类型**:
|
||||
- Python 是动态类型语言,变量类型在运行时决定,这与静态类型语言(如 C# 和 Java)形成鲜明对比,后者在编译时必须声明变量类型。
|
||||
4. **多范式支持**:
|
||||
- Python 支持多种编程范式(如面向对象、函数式编程),而一些语言则更倾向于某一特定范式,如 Java 主要是面向对象的。
|
||||
5. **强大的标准库**:
|
||||
- Python 附带了一个丰富的标准库,提供了大量现成的模块和功能,而其他语言可能需要依赖外部库或框架。
|
||||
6. **社区和文化**:
|
||||
- Python 拥有一个积极的社区,强调开放和共享,鼓励用户贡献代码和文档,而其他语言的社区文化可能更加保守或封闭。
|
||||
|
||||
# Python环境部署
|
||||
|
||||
## Python解释器
|
||||
|
||||
- 打开官网:https://www.python.org/downloads
|
||||
- 找到对应的版本,这里选择版本3.9.8
|
||||
|
||||
**3.9.8版本**下载链接:https://www.python.org/ftp/python/3.9.8/python-3.9.8-amd64.exe
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902111134272.png" alt="image-20240902111134272" style="zoom:80%;" />
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902111545070.png" alt="image-20240902111545070" style="zoom:80%;" />
|
||||
|
||||
打开安装包,添加环境变量,可以选择默认安装或者自定义安装(一般自定义安装主要是修改安装路径)
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902112236819.png" alt="image-20240902112236819" style="zoom:80%;" />
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902142136568.png" alt="image-20240902142136568" style="zoom:80%;" />
|
||||
|
||||
**注意:**必须勾选上下面的"Add Python 3.9 to PATH"(添加到系统环境变量中)
|
||||
|
||||
**测试是否安装成功**
|
||||
|
||||
在键盘上按下`win+R`然后在左下弹出窗口中输入`cmd`回车
|
||||
|
||||
在cmd终端中输入python,如果可以看到如下内容,说明python环境安装成功,并且请核对版本号是否与我们安装的一致....
|
||||
|
||||
```bash
|
||||
C:\Users\test>python
|
||||
Python 3.9.8 (tags/v3.9.8:bb3fdcf, Nov 5 2021, 20:48:33) [MSC v.1929 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>>
|
||||
```
|
||||
|
||||
## Python编辑器
|
||||
|
||||
Python可用的编辑器有很多,因为编辑器只负责编写代码,实际的代码执行还是由我们刚刚安装的解释器进行编译解释。所以编写Python代码对编辑器的要求不是很高。不过,为了便于我们敲代码,我们还是要选择一些更加高级,功能更多的编辑器来使用。这样在编写代码的时候可以事半功倍
|
||||
|
||||
对于Python而言,最出名,最好用的编辑器就是pycharm了。我们后续学习也主要使用pycharm编辑器。
|
||||
|
||||
### 其他编辑器
|
||||
|
||||
**以下仅作为了解即可...**
|
||||
|
||||
1. **vim编辑器**
|
||||
|
||||
Vim(Vi IMproved)是一个高度可配置的文本编辑器,它源自于一个名为Vi的早期Unix编辑器。Vim的设计目标是提供一种高效的方式来编辑文本文件,它广泛应用于程序员和系统管理员中,因为它支持多种编程语言的语法高亮、代码补全、编译和错误跳转等功能。
|
||||
|
||||
Vim是一个主要基于命令行的编辑器,几乎所有的操作,如:复制、粘贴、删除等待,都需要通过指令来完成。所以说使用难度相对较高,我们后面的云计算部分会深入学习...
|
||||
|
||||
2. **Sublim Text**
|
||||
|
||||
Sublime Text 是一个代码编辑器(Sublime Text 2是收费软件,但可以无限期试用)
|
||||
|
||||
Sublime Text是由程序员Jon Skinner于2008年1月份所开发出来,它最初被设计为一个具有丰富扩展功能的Vim。
|
||||
|
||||
Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。
|
||||
|
||||
还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。
|
||||
|
||||
Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。
|
||||
|
||||
下载地址:http://www.sublimetext.com/3
|
||||
|
||||
<img src="./01.Python环境部署/image-20240904101732444.png" alt="image-20240904101732444" style="zoom: 80%;" />
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902143634827.png" alt="image-20240902143634827" style="zoom:80%;" />
|
||||
|
||||
### Pycharm的安装
|
||||
|
||||
下载地址:http://www.jetbrains.com/pycharm/download/#section=windows
|
||||
|
||||
因为社区版可能会缺少部分功能,所以直接选择专业版
|
||||
|
||||
**安装过程:**
|
||||
|
||||
1. 下载安装包并且安装
|
||||
2. 使用Eagleslab提供的补丁工具进行激活
|
||||
3. 查看设置-->About
|
||||
|
||||
**上述操作环节较多,认真观看老师的操作~**
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902145526575.png" alt="image-20240902145526575" style="zoom:80%;" />
|
||||
|
||||
## 创建第一个项目
|
||||
|
||||
1. 点击New Project来创建一个项目,项目Name和Location可以自定义
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902145711220.png" alt="image-20240902145711220" style="zoom:80%;" />
|
||||
|
||||
2. 在项目名称上右键来创建一个Python File
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902145939086.png" alt="image-20240902145939086" style="zoom: 80%;" />
|
||||
|
||||
3. 编写第一个Python代码
|
||||
|
||||
```python
|
||||
print('Hello World!')
|
||||
```
|
||||
|
||||
然后右键->Run demo.py来运行
|
||||
|
||||
<img src="./01.Python环境部署/image-20240902150205122.png" alt="image-20240902150205122" style="zoom:80%;" />
|
||||
|
||||
```bash
|
||||
# Output
|
||||
C:\Users\test\PycharmProjects\pythonProject\.venv\Scripts\python.exe C:\Users\test\PycharmProjects\pythonProject\demo.py
|
||||
hello world
|
||||
|
||||
Process finished with exit code 0
|
||||
```
|
||||
|
||||
## Pycharm优化
|
||||
|
||||
1. 中文支持
|
||||
2. 字体大小调节
|
||||
3. 主题更改
|
||||
|
||||
......
|
||||
BIN
project1/01.Python环境部署.pdf
Normal file
BIN
project1/01.Python环境部署/image-20240902103540169.png
Normal file
|
After Width: | Height: | Size: 411 KiB |
BIN
project1/01.Python环境部署/image-20240902110217569.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
project1/01.Python环境部署/image-20240902111134272.png
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
project1/01.Python环境部署/image-20240902111545070.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
project1/01.Python环境部署/image-20240902112236819.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
project1/01.Python环境部署/image-20240902142136568.png
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
project1/01.Python环境部署/image-20240902143634827.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
project1/01.Python环境部署/image-20240902145526575.png
Normal file
|
After Width: | Height: | Size: 117 KiB |
BIN
project1/01.Python环境部署/image-20240902145711220.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
project1/01.Python环境部署/image-20240902145939086.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
project1/01.Python环境部署/image-20240902150205122.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
project1/01.Python环境部署/image-20240904101732444.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
project1/01.Python环境部署/image-20240920215125704.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
28
project1/[任务书]环境部署.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 任务需求
|
||||
|
||||
## 安装Python解释器
|
||||
|
||||
- 掌握Python的优势,了解Python开发环境的使用
|
||||
|
||||
- 安装好Python解释器,并且能够在命令行(cmd)中看到Python的版本号
|
||||
|
||||

|
||||
|
||||
## 正确配置Pycharm
|
||||
|
||||
- 安装pycharm开发环境并激活
|
||||
|
||||

|
||||
|
||||
- 在pycharm中安装好汉化组件
|
||||
|
||||

|
||||
|
||||
- 运行`Hello World` 程序,确保整个python工作环境正常
|
||||
|
||||

|
||||
|
||||
> <span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业1提交的内容</span>
|
||||
>
|
||||
> - Pycharm程序运行成功Hello world的截图,单独发送给组长
|
||||
|
||||
BIN
project1/[任务书]环境部署/image-20241130142625526.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
project1/[任务书]环境部署/image-20241130142742171.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
project1/[任务书]环境部署/image-20241130142910916.png
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
project1/[任务书]环境部署/image-20241130143001558.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
project10/.DS_Store
vendored
Normal file
431
project10/01.web框架的本质.md
Normal file
@@ -0,0 +1,431 @@
|
||||
# HTTP的请求头和响应头
|
||||
|
||||

|
||||
|
||||
浏览器与服务器通信,主要是依靠请求报文来向服务器表示想要获取到什么样的资源,服务器会用响应报文来表达服务器会员的数据的情况
|
||||
|
||||
# 自定义web框架
|
||||
|
||||
web应用本质上就是一个socket服务端,浏览器是socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响应,按照http协议的请求协议发送请求,服务端按照http协议的响应协议来响应请求,这样的网络通信,我们就可以自己实现Web框架了。
|
||||
|
||||
准备一个html文件
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>测试页面</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>标题1</h1>
|
||||
<img src="https://iproute.cn/medias/logo.png" alt="头像">
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
编写python的socket服务端
|
||||
|
||||
```python
|
||||
import socket
|
||||
sk = socket.socket()
|
||||
# 允许地址复用
|
||||
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sk.bind(('127.0.0.1',8080))
|
||||
sk.listen()
|
||||
conn,addr = sk.accept()
|
||||
b_msg = conn.recv(1024)
|
||||
str_msg = b_msg.decode('utf-8')
|
||||
conn.send(b'HTTP/1.1 200 ok \r\n\r\n')
|
||||
conn.send(b'hello')
|
||||
conn.close()
|
||||
sk.close()
|
||||
```
|
||||
|
||||
运行服务端之后,浏览器访问http://127.0.0.1:8080,浏览器传给socket的内容如下
|
||||
|
||||

|
||||
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
|
||||
Accept-Encoding: gzip, deflate, br, zstd
|
||||
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8
|
||||
Cache-Control: max-age=0
|
||||
Connection: keep-alive
|
||||
Host: 127.0.0.1:8080
|
||||
Sec-Fetch-Dest: document
|
||||
Sec-Fetch-Mode: navigate
|
||||
Sec-Fetch-Site: none
|
||||
Sec-Fetch-User: ?1
|
||||
Upgrade-Insecure-Requests: 1
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
|
||||
sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
|
||||
sec-ch-ua-mobile: ?0
|
||||
sec-ch-ua-platform: "macOS"
|
||||
```
|
||||
|
||||
修改socket服务端,让其返回网页内容
|
||||
|
||||
```python
|
||||
import socket
|
||||
sk = socket.socket()
|
||||
# 允许地址复用
|
||||
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sk.bind(('127.0.0.1',8080))
|
||||
sk.listen()
|
||||
conn,addr = sk.accept()
|
||||
b_msg = conn.recv(1024)
|
||||
str_msg = b_msg.decode('utf-8')
|
||||
print(str_msg)
|
||||
conn.send(b'HTTP/1.1 200 ok \r\n\r\n')
|
||||
with open('test.html','rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
sk.close()
|
||||
```
|
||||
|
||||
这样就可以将网页内容返回给浏览器了
|
||||
|
||||
如果想要在网页中携带本地路径的图片,那么修改html代码
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>测试页面</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>标题1</h1>
|
||||
<img src="logo.png" alt="头像">
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
然后修改socket服务端
|
||||
|
||||
```python
|
||||
import socket
|
||||
sk = socket.socket()
|
||||
# 允许地址复用
|
||||
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sk.bind(('127.0.0.1',8080))
|
||||
sk.listen()
|
||||
while 1: # 浏览器多次访问,所以需要while
|
||||
conn,addr = sk.accept()
|
||||
b_msg = conn.recv(1024)
|
||||
str_msg = b_msg.decode('utf-8')
|
||||
path = str_msg.split('\r\n')[0].split(' ')[1]
|
||||
print('path>>>',path)
|
||||
conn.send(b'HTTP/1.1 200 ok \r\n\r\n')
|
||||
if path == '/':
|
||||
with open('test.html','rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close() # HTTP协议是短链接的,一次请求对应一次响应,这个请求就结束了,所以我们需要写上close,不然浏览器自己断了
|
||||
elif path == '/logo.png':
|
||||
with open('logo.png','rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
sk.close()
|
||||
```
|
||||
|
||||
可以改成使用函数的版本
|
||||
|
||||
```python
|
||||
import socket
|
||||
sk = socket.socket()
|
||||
# 允许地址复用
|
||||
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sk.bind(('127.0.0.1',8080))
|
||||
sk.listen()
|
||||
def func1(conn):
|
||||
with open('test.html', 'rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
def func2(conn):
|
||||
with open('logo.png', 'rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
|
||||
while 1:
|
||||
conn,addr = sk.accept()
|
||||
b_msg = conn.recv(1024)
|
||||
str_msg = b_msg.decode('utf-8')
|
||||
path = str_msg.split('\r\n')[0].split(' ')[1]
|
||||
print('path>>>',path)
|
||||
conn.send(b'HTTP/1.1 200 ok \r\n\r\n')
|
||||
if path == '/':
|
||||
func1(conn)
|
||||
elif path == '/logo.png':
|
||||
func2(conn)
|
||||
sk.close()
|
||||
```
|
||||
|
||||
现在还不支持高并发的情况,可以加上多线程
|
||||
|
||||
```python
|
||||
import socket
|
||||
from threading import Thread
|
||||
|
||||
sk = socket.socket()
|
||||
# 允许地址复用
|
||||
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sk.bind(('127.0.0.1',8080))
|
||||
sk.listen()
|
||||
def func1(conn):
|
||||
with open('test.html', 'rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
def func2(conn):
|
||||
with open('logo.png', 'rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
|
||||
while 1:
|
||||
conn,addr = sk.accept()
|
||||
b_msg = conn.recv(1024)
|
||||
str_msg = b_msg.decode('utf-8')
|
||||
path = str_msg.split('\r\n')[0].split(' ')[1]
|
||||
print('path>>>',path)
|
||||
conn.send(b'HTTP/1.1 200 ok \r\n\r\n')
|
||||
if path == '/':
|
||||
t = Thread(target=func1,args=(conn,))
|
||||
t.start()
|
||||
elif path == '/logo.png':
|
||||
t = Thread(target=func2,args=(conn,))
|
||||
t.start()
|
||||
sk.close()
|
||||
```
|
||||
|
||||
替换字符串,实现不同的时间访问返回时间戳模拟动态内容
|
||||
|
||||
在网页中,用特殊的符号`@@666@@`表示需要被替换掉的地方,修改html代码
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>测试页面</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>标题1</h1>
|
||||
<img src="logo.png" alt="头像">
|
||||
<h2>@@666@@</h2>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
修改socket服务端
|
||||
|
||||
```python
|
||||
import socket
|
||||
from threading import Thread
|
||||
import time
|
||||
|
||||
sk = socket.socket()
|
||||
# 允许地址复用
|
||||
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sk.bind(('127.0.0.1',8080))
|
||||
sk.listen()
|
||||
def func1(conn):
|
||||
with open('test.html', 'r',encoding="utf-8") as f:
|
||||
f_data = f.read()
|
||||
now = str(time.time())
|
||||
f_data = f_data.replace("@@666@@",now).encode('utf-8')
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
def func2(conn):
|
||||
with open('logo.png', 'rb') as f:
|
||||
f_data = f.read()
|
||||
conn.send(f_data)
|
||||
conn.close()
|
||||
|
||||
while 1:
|
||||
conn,addr = sk.accept()
|
||||
b_msg = conn.recv(1024)
|
||||
str_msg = b_msg.decode('utf-8')
|
||||
path = str_msg.split('\r\n')[0].split(' ')[1]
|
||||
print('path>>>',path)
|
||||
conn.send(b'HTTP/1.1 200 ok \r\n\r\n')
|
||||
if path == '/':
|
||||
t = Thread(target=func1,args=(conn,))
|
||||
t.start()
|
||||
elif path == '/logo.png':
|
||||
t = Thread(target=func2,args=(conn,))
|
||||
t.start()
|
||||
sk.close()
|
||||
```
|
||||
|
||||
# WSGI
|
||||
|
||||
WSGI(Web Server Gateway Interface)是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。
|
||||
|
||||
常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。
|
||||
|
||||
# 模板渲染JinJa2
|
||||
|
||||
上面的过程中用`@@666@@`替换了动态的内容, 其实模板渲染有个现成的工具: `jinja2`
|
||||
|
||||
安装`jinja2`
|
||||
|
||||
```bash
|
||||
pip install jinja2 -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
```
|
||||
|
||||
编写html文件
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>jinja2</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>姓名:{{name}}</h1>
|
||||
<h1>爱好:</h1>
|
||||
<ul>
|
||||
{% for hobby in hobby_list %}
|
||||
<li>{{hobby}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
编写wsgi服务端
|
||||
|
||||
```python
|
||||
from wsgiref.simple_server import make_server
|
||||
from jinja2 import Template
|
||||
|
||||
|
||||
def index():
|
||||
with open("test.html", "r", encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
template = Template(data)
|
||||
ret = template.render({"name": "张三", "hobby_list": ["抽烟", "喝酒", "烫头"]})
|
||||
return [bytes(ret, encoding="utf-8"), ]
|
||||
|
||||
|
||||
URL_LIST = [
|
||||
("/index/", index),
|
||||
]
|
||||
|
||||
|
||||
def run_server(environ, start_response):
|
||||
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])
|
||||
url = environ['PATH_INFO']
|
||||
func = None
|
||||
for i in URL_LIST:
|
||||
if i[0] == url:
|
||||
func = i[1]
|
||||
break
|
||||
if func:
|
||||
return func()
|
||||
else:
|
||||
return [bytes("404没有该页面", encoding="utf8"), ]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
http = make_server('', 8000, run_server)
|
||||
print("Serving HTTP on port 8000...")
|
||||
http.serve_forever()
|
||||
|
||||
```
|
||||
|
||||
下面演示从数据库中提取内容进行替换
|
||||
|
||||
- mysql点此下载:https://www.123865.com/s/BKNfTd-WDXKA提取码:6666
|
||||
|
||||
```sql
|
||||
-- 创建数据库
|
||||
create database pywebdb;
|
||||
|
||||
-- 进入数据库中
|
||||
use pywebdb
|
||||
|
||||
-- 创建表
|
||||
CREATE TABLE user(
|
||||
id int auto_increment PRIMARY KEY,
|
||||
name CHAR(10) NOT NULL,
|
||||
hobby CHAR(20) NOT NULL
|
||||
)engine=innodb DEFAULT charset=UTF8;
|
||||
|
||||
-- 插入一个数据
|
||||
INSERT into user (name, hobby) VALUES ('张三', '抽烟,喝酒,烫头');
|
||||
|
||||
-- 查看插入的数据
|
||||
SELECT * FROM user;
|
||||
```
|
||||
|
||||
修改socket服务端
|
||||
|
||||
```python
|
||||
import pymysql
|
||||
from wsgiref.simple_server import make_server
|
||||
from jinja2 import Template
|
||||
|
||||
def index(name,hobby):
|
||||
with open("index.html", "r", encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
template = Template(data)
|
||||
ret = template.render({"name":name, "hobby_list":hobby})
|
||||
return [bytes(ret, encoding="utf-8"),]
|
||||
|
||||
URL_LIST = [
|
||||
("/index/", index),
|
||||
]
|
||||
|
||||
def run_server(environ, start_response):
|
||||
conn = pymysql.connect(
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
user="root",
|
||||
passwd="test123",
|
||||
db="pywebdb",
|
||||
charset="utf8"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('select * from user')
|
||||
data = cursor.fetchone()
|
||||
name=data[1]
|
||||
hobby=data[2]
|
||||
conn.close()
|
||||
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'),])
|
||||
url = environ['PATH_INFO']
|
||||
func = None
|
||||
for i in URL_LIST:
|
||||
if i[0] == url:
|
||||
func = i[1]
|
||||
break
|
||||
if func:
|
||||
return func(name,hobby)
|
||||
else:
|
||||
return [bytes("404没有该页面", encoding="utf8"),]
|
||||
|
||||
if __name__ == '__main__':
|
||||
http = make_server('',8000,run_server)
|
||||
print("Serving HTTP on port 8000...")
|
||||
http.serve_forever()
|
||||
```
|
||||
|
||||
模板的原理就是字符串替换,我们只要在HTML页面中遵循jinja2的语法规则写上,其内部就会按照指定的语法进行相应的替换,从而达到动态的返回内容。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
project10/01.web框架的本质/a856a010-ba01-45f7-8e59-8234ac2e9488.jpeg
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
project10/01.web框架的本质/image-20241210163939143.png
Normal file
|
After Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 180 KiB |
22
project10/02.[任务书]爬虫照片墙.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 爬虫照片墙
|
||||
|
||||
## 需求
|
||||
|
||||
- 目前已经得到照片墙前端代码:https://www.123865.com/s/BKNfTd-E8XKA提取码:6666
|
||||
- 现在考虑将前面写的图片爬虫与此前端进行结合,通过爬虫爬到的图片可以显示到这个照片墙的网页上
|
||||
|
||||
## 参考代码
|
||||
|
||||
- 参考代码下载地址:https://www.123865.com/s/BKNfTd-o8XKA提取码:6666
|
||||
- 效果展示(只是效果展示,本来就没有声音)
|
||||
|
||||
<video src="https://static.eagleslab.com/python-c73d2e01-83a8-17ef-e0b9-59b3ab5fc599/project10/02.效果展示.mp4" width="100%" controls>
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
|
||||
|
||||
|
||||
><span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业10.1提交的内容</span>
|
||||
>
|
||||
>- 理解程序的运行逻辑
|
||||
>- 程序运行成功的截图,单独发送给组长
|
||||
235
project11/01.Flask框架.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# Flask简介
|
||||
|
||||
`flask`是一款非常流行的`Python Web`框架,出生于2010年,作者是`Armin Ronacher`,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常受欢迎,进而成为一个正式的项目。
|
||||
|
||||
`flask`自2010年发布第一个版本以来,大受欢迎,深得开发者的喜爱,目前在`Github`上的Star数已经超过`55.5k`了,有超`Django`之趋势。`flask`能如此流行的原因,可以分为以下几点:
|
||||
|
||||
- 微框架、简洁、只做他需要做的,给开发者提供了很大的扩展性。
|
||||
- Flask和相应的插件写得很好,用起来很爽。
|
||||
- 开发效率非常高,比如使用`SQLAlchemy`的`ORM`操作数据库可以节省开发者大量书写`sql`的时间。
|
||||
|
||||
`Flask`的灵活度非常之高,他不会帮你做太多的决策,一些你都可以按照自己的意愿进行更改。比如:
|
||||
|
||||
- 使用`Flask`开发数据库的时候,具体是使用`SQLAlchemy`还是`MongoEngine`,选择权完全掌握在你自己的手中。区别于`Django`,`Django`内置了非常完善和丰富的功能,并且如果你想替换成你自己想要的,要么不支持,要么非常麻烦。
|
||||
- 把默认的`Jinija2`模板引擎替换成其他模板引擎都是非常容易的。
|
||||
|
||||
# 安装flask
|
||||
|
||||
在pycharm中可以在如下位置安装
|
||||
|
||||

|
||||
|
||||
在命令行中可以输入如下命令安装
|
||||
|
||||
```
|
||||
pip install flask -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
```
|
||||
|
||||
# Flask项目
|
||||
|
||||
## 运行helloworld
|
||||
|
||||
```python
|
||||
import flask
|
||||
# 导入flask框架
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
# 传入__name__初始化一个Flask实例
|
||||
|
||||
@app.route('/')
|
||||
# app.route装饰器映射URL和执行的函数。这个设置将根URL映射到了hello_world函数上
|
||||
def hello_world():
|
||||
return 'Hello'
|
||||
# 返回的内容就会呈现到浏览器上
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 运行本项目,host=0.0.0.0可以让其他电脑也能访问到该网站,port指定访问的端口。默认的host是127.0.0.1,port为5000
|
||||
app.run(debug=True,host='0.0.0.0',port=8080)
|
||||
# 在pycharm中,debug,host,port等代码中的设置无效
|
||||
```
|
||||
|
||||
如果在pycharm中想要修改调试的地址和端口可以进行如下设置
|
||||
|
||||

|
||||
|
||||
# URL与视图
|
||||
|
||||
## URL与函数的映射
|
||||
|
||||
一个`URL`要与执行函数进行映射,使用的是`@app.route`装饰器。`@app.route`装饰器中,可以指定`URL`的规则来进行更加详细的映射,比如现在要映射一个文章详情的`URL`,文章详情的`URL`是`/article/id/`,id有可能为1、2、3…,那么可以通过以下方式:
|
||||
|
||||
```python
|
||||
@app.route('/article/<id>/')
|
||||
# 可以用<xxx>来读取对应的内容
|
||||
def article(id):
|
||||
return f'{id}article detail'
|
||||
```
|
||||
|
||||

|
||||
|
||||
其中`<id>`,尖括号是固定写法,语法为`<variable>`,`variable`默认的数据类型是字符串。如果需要指定类型,则要写成`<converter:variable>`,其中`converter`就是类型名称,可以有以下几种:
|
||||
|
||||
- string: 默认的数据类型,接受没有任何斜杠`/`的字符串。
|
||||
- int: 整形
|
||||
- float: 浮点型。
|
||||
- path: 和`string`类似,但是可以传递斜杠`/`。
|
||||
- uuid: `uuid`类型的字符串。
|
||||
- any:可以指定多种路径
|
||||
|
||||
举例说明
|
||||
|
||||
```python
|
||||
@app.route('/guess/<int:num>')
|
||||
# 由于指定了int类型,所以num可以直接和整数型比较大小
|
||||
def guess(num):
|
||||
if num < 66:
|
||||
return "你猜的数字小了"
|
||||
elif num > 66:
|
||||
return "你猜的数字大了"
|
||||
else:
|
||||
return "你猜对了"
|
||||
```
|
||||
|
||||
访问结果
|
||||
|
||||

|
||||
|
||||
如果传入一个不是int类型的,就无法触发这个路由,就会返回404
|
||||
|
||||

|
||||
|
||||
关于any类型可以看下面这个案例
|
||||
|
||||
```python
|
||||
@app.route('/user/<any(article,blog):url_path>')
|
||||
# 在/user/后面只能是article和blog二选一,并且会被传递到url_path变量
|
||||
def url_path(url_path):
|
||||
return f"你输入的是{url_path},此处只能是article或者blog"
|
||||
```
|
||||
|
||||

|
||||
|
||||
如果输入了别的字符串,就会返回404
|
||||
|
||||

|
||||
|
||||
## 构造URL
|
||||
|
||||
一般我们通过一个`URL`就可以执行到某一个函数。如果反过来,我们知道一个函数,怎么去获得这个`URL`呢?`url_for`函数就可以帮我们实现这个功能。`url_for()`函数接收两个及以上的参数,他接收**函数名**作为第一个参数,接收对应**URL规则的命名参数**,如果还出现其他的参数,则会添加到`URL`的后面作为**查询参数**。
|
||||
|
||||
通过构建`URL`的方式而选择直接在代码中拼`URL`的原因有两点:
|
||||
|
||||
1. 将来如果修改了`URL`,但没有修改该`URL`对应的函数名,就不用到处去替换`URL`了。
|
||||
2. `url_for()`函数会转义一些特殊字符和`unicode`字符串,这些事情`url_for`会自动的帮我们搞定。
|
||||
|
||||
下面用一个例子来进行解释:
|
||||
|
||||
```python
|
||||
from flask import Flask,url_for
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/article/<id>/')
|
||||
def article(id):
|
||||
return '%s article detail' % id
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return url_for("article",id=1)
|
||||
# 可以使用url_for来帮我们构造一个url,会帮助我们检查此url的合法性
|
||||
```
|
||||
|
||||
在访问的时候,会打印出`/article/1/`。
|
||||
|
||||
## 指定URL末尾的斜杠
|
||||
|
||||
当访问一个结尾不带斜线的`URL`:`/article`,会被重定向到带斜线的`URL`:`/article/`上去。但是当我们在定义`article`的`url`的时候,如果在末尾没有加上斜杠,但是在访问的时候又加上了斜杠,这时候就会抛出一个`404`错误页面了:
|
||||
|
||||
```python
|
||||
@app.route('/test')
|
||||
def haha():
|
||||
return '你好'
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 指定HTTP方法
|
||||
|
||||
在`@app.route()`中可以传入一个关键字参数`methods`来指定本方法支持的`HTTP`方法,默认情况下,只能使用`GET`请求,看以下例子:
|
||||
|
||||
```python
|
||||
@app.route('/search/')
|
||||
def search():
|
||||
# return f"你输入的要搜索的东西是{request.args['kw']}"
|
||||
return f"你输入的要搜索的东西是{request.args.get('kw')}"
|
||||
# 可以和字典一样去取对应的值
|
||||
# http://xxxx:5000/search?kw=xxx
|
||||
```
|
||||
|
||||
如果使用post提交就会触发错误
|
||||
|
||||
- 调试工具hackbar下载地址:https://www.123865.com/s/BKNfTd-oKXKA提取码:6666
|
||||
- 安装教程见录屏
|
||||
|
||||

|
||||
|
||||
如果想要使用post请求,可以看如下例子
|
||||
|
||||
```python
|
||||
from flask import Flask,request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/login/',methods=['POST'])
|
||||
def login():
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
if username == 'admin' and password == '123456':
|
||||
return 'Logged in successfully'
|
||||
else:
|
||||
return 'Invalid username or password'
|
||||
```
|
||||
|
||||
尝试登陆一下
|
||||
|
||||

|
||||
|
||||
## 页面跳转和重定向
|
||||
|
||||
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。
|
||||
|
||||
- 永久性重定向:`http`的状态码是`301`,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入`www.ubnt.com`的时候,会被重定向到`ui.com.cn`,因为`www.ubnt.com`这个网址不是中国区的,跳转到中国区地址`ui.com.cn`,所以这种情况下应该用永久重定向。
|
||||
- 暂时性重定向:`http`的状态码是`302`,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
|
||||
|
||||
在`flask`中,重定向是通过`flask.redirect(location,code=302)`这个函数来实现的,`location`表示需要重定向到的`URL`,应该配合之前讲的`url_for()`函数来使用,`code`表示采用哪个重定向,默认是`302`也即`暂时性重定向`,可以修改成`301`来实现永久性重定向。
|
||||
|
||||
以下来看一个例子,关于在`flask`中怎么使用重定向:
|
||||
|
||||
```python
|
||||
from flask import Flask, request, session, redirect, url_for
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = '啦啦啦,我是买糕的小行家'
|
||||
# 使用session的话,需要配置一个secret_key,内容随意,最好别人想不到
|
||||
@app.route('/login/',methods=['POST','GET'])
|
||||
def login():
|
||||
if 'username' not in request.form and 'password' not in request.form:
|
||||
# 如果没有携带用户名和密码,就显示请登陆
|
||||
return "请登陆"
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
if username == 'admin' and password == '123456':
|
||||
session['username'] = 'admin'
|
||||
# 登陆成功之后,服务器存储session值
|
||||
return 'Logged in successfully'
|
||||
else:
|
||||
return 'Invalid username or password'
|
||||
|
||||
@app.route("/profile/",methods=['GET'])
|
||||
def profile():
|
||||
if 'username' in session:
|
||||
return f"欢迎用户{session['username']}"
|
||||
# 如果已经登陆,就欢迎
|
||||
else:
|
||||
return redirect(url_for('login'))
|
||||
# 如果cookie中没有合法的session值,就重定向去登陆
|
||||
```
|
||||
|
||||
BIN
project11/01.Flask框架/image-20240325144818915.png
Normal file
|
After Width: | Height: | Size: 171 KiB |
BIN
project11/01.Flask框架/image-20240325150133886.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
project11/01.Flask框架/image-20240325150826433.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
project11/01.Flask框架/image-20240325151305950.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
project11/01.Flask框架/image-20240325151332770.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
project11/01.Flask框架/image-20240325151707414.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
project11/01.Flask框架/image-20240325151736882.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
project11/01.Flask框架/image-20240325152716861.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
project11/01.Flask框架/image-20240325153334862.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
project11/01.Flask框架/image-20240325153641414.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
46
project11/02.[任务书]开发搜索引擎.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 开发搜索引擎
|
||||
|
||||
## 需求
|
||||
|
||||
- 小明同学看着搜索引擎感觉功能很神奇,想要花亿点点时间,自己开发一个,你能帮帮他么?
|
||||
- 利用flask作为后端开发一个和百度一样体验的搜索引擎
|
||||
- 目前已有前端代码:https://www.123865.com/s/BKNfTd-QKXKA提取码:6666
|
||||
|
||||
## 参考代码
|
||||
|
||||
- 此程序涉及到前后端多个代码文件
|
||||
- 项目压缩包下载地址:https://www.123865.com/s/BKNfTd-EKXKA提取码:6666
|
||||
|
||||
```python
|
||||
import flask
|
||||
from flask import request, redirect
|
||||
|
||||
app = flask.Flask(__name__, static_folder='static')
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return flask.render_template('index.html')
|
||||
|
||||
|
||||
@app.route("/search/", methods=['POST'])
|
||||
def search():
|
||||
# 从post中获取wd的提交内容
|
||||
wd = request.form.get('wd')
|
||||
# 重定向到构造好的百度搜索连接
|
||||
return redirect(f"https://www.baidu.com/s?wd={wd}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='0.0.0.0', port=8088)
|
||||
```
|
||||
|
||||
<video src="https://static.eagleslab.com/python-c73d2e01-83a8-17ef-e0b9-59b3ab5fc599/project11/效果展示.mp4" width="100%" controls>
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
|
||||
|
||||
><span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业11.1提交的内容</span>
|
||||
>
|
||||
>- 理解程序的运行逻辑
|
||||
>- 程序运行成功的截图,单独发送给组长
|
||||
686
project12/01.初识HTML.md
Normal file
@@ -0,0 +1,686 @@
|
||||
# HTML的概述
|
||||
|
||||
## HTML的概念
|
||||
|
||||
**HTML** 全称为 HyperText Markup Language,译为<font color=#0000ff>**超文本标记语言**</font>。
|
||||
|
||||
HTML 不是一种编程语言,是一种描述性的**标记语言**。
|
||||
|
||||
**作用**:HTML是负责描述文档**语义**的语言。
|
||||
|
||||
## 概览:超文本
|
||||
|
||||
所谓的超文本,有两层含义:
|
||||
|
||||
(1)图片、音频、视频、动画、多媒体等内容,成为超文本,因为它们超出了文本的限制。
|
||||
|
||||
(2)不仅如此,它还可以从一个文件跳转到另一个文件,与世界各地主机的文件进行连接。即:超级链接文本。
|
||||
|
||||
## 概念:标记语言
|
||||
|
||||
HTML 不是一种编程语言,是一种描述性的**标记语言**。这主要有两层含义:
|
||||
|
||||
(1)**标记语言是一套标记标签**。比如:标签`<a>`表示超链接、标签`<img>`表示图片、标签`<h1>`表示一级标题等等,它们都是属于 HTML 标签。
|
||||
|
||||
说的通俗一点就是:网页是由网页元素组成的,这些元素是由 HTML 标签描述出来,然后通过浏览器解析,就可以显示给用户看了。
|
||||
|
||||
(2)编程语言是有编译过程的,而标记语言没有编译过程,HTML标签是直接由浏览器解析执行。
|
||||
|
||||
## HTML是负责描述文档语义的语言
|
||||
|
||||
HTML 格式的文件是一个纯本文文件(就是用txt文件改名而成),用一些标签来描述语义,这些标签在浏览器页面上是无法直观看到的,所以称之为“超文本标记语言”。
|
||||
|
||||
接下来,我们需要学习 HTML 中的很多“标签对儿”,这些“标签对儿”能够给文本不同的语义。
|
||||
|
||||
比如,面试的时候问你,`<h1>` 标签有什么作用?
|
||||
|
||||
- 正确答案:给文本增加主标题的语义。
|
||||
- 错误答案:给文字加粗、加黑、变大。
|
||||
|
||||
关乎“语义”的更深刻理解,等接下来我们学习了各种标签,就明白了。
|
||||
|
||||
# HTML的历史
|
||||
|
||||

|
||||
|
||||
其中,我们专门来对XHTML做一个介绍。
|
||||
|
||||
**XHTML介绍:**
|
||||
XHTML:Extensible Hypertext Markup Language,可扩展超文本标注语言。
|
||||
XHTML的主要目的是为了<font color="blue">**取代HTML**</font>,也可以理解为HTML的升级版。
|
||||
HTML的标记书写很不规范,会造成其它的设备(ipad、手机、电视等)无法正常显示。
|
||||
XHTML与HTML4.0的标记基本上一样。
|
||||
XHTML是<font color="blue">**严格的、纯净的**</font>HTML。
|
||||
|
||||
我们稍后将对XHTML的编写规范进行介绍。
|
||||
|
||||
# HTML的专有名词
|
||||
|
||||
- 网页 :由各种标记组成的一个页面就叫网页。
|
||||
- 主页(首页) : 一个网站的起始页面或者导航页面。
|
||||
- 标记: 比如`<p>`称为开始标记 ,`</p>`称为结束标记,也叫标签。每个标签都规定好了特殊的含义。
|
||||
- 元素:比如`<p>内容</p>`称为元素.
|
||||
- 属性:给每一个标签所做的辅助信息。
|
||||
- XHTML:符合XML语法标准的HTML。
|
||||
- DHTML:dynamic,动态的。`javascript + css + html`合起来的页面就是一个 DHTML。
|
||||
- HTTP:超文本传输协议。用来规定客户端浏览器和服务端交互时数据的一个格式。SMTP:邮件传输协议,FTP:文件传输协议。
|
||||
|
||||
# 书写第一个 HTML 页面
|
||||
|
||||
我们打开 VS Code 软件,新建一个文件,名叫`test.html`(注意,文件名是`test`,后缀名是`html`),保存到本地。
|
||||
|
||||
- vscode下载地址:https://www.123865.com/s/BKNfTd-SUXKA提取码:6666
|
||||
|
||||
紧接着,在文件里,输入`!`,然后按一下键盘上的`Tab`键,就可以自动生成如下内容:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
上面的内容,就是 html 页面的骨架。我们在此基础之上,新增几个标签,完整代码如下:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h3>我是三级标题</h3>
|
||||
<img src="" alt="">
|
||||
<a href="https://www.jd.com">我是超链接,可以点击一下</a>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
标签写完之后,我们用 chrome 浏览器打开上面这个`test.html`文件,看看页面效果:
|
||||
|
||||
到此,第一个简单的 HTML 页面就写完了。是不是很有成就感?
|
||||
|
||||
|
||||
|
||||
# HTML结构详解
|
||||
|
||||
HTML标签通常是成对出现的(<font color="blue">**双边标记**</font>),比如 `<div>` 和 `</div>`;也有少部分单标签(<font color="blue">**单边标记**</font>),如:`<br />`、`<hr />`和`<img src="images/1.jpg" />`等。
|
||||
|
||||
属性与标记之间、各属性之间需要以空格隔开。属性值以双引号括起来。
|
||||
|
||||
## html骨架标签分类
|
||||
|
||||
| 标签名 | 定义 | 说明 |
|
||||
| ------------------ | :--------: | :------------------------------------------------------ |
|
||||
| `<html></html>` | HTML标签 | 页面中最大的标签,我们成为根标签 |
|
||||
| `<head></head>` | 文档的头部 | 注意在head标签中我们必须要设置的标签是title |
|
||||
| `<titile></title>` | 文档的标题 | 让页面拥有一个属于自己的网页标题 |
|
||||
| `<body></body>` | 文档的主体 | 元素包含文档的所有内容,页面内容 基本都是放到body里面的 |
|
||||
|
||||
## 快速生成html的骨架
|
||||
|
||||
在 VS Code 中新建 html 文件,输入`!`,按 `Tab`键后,自动生成的代码如下:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
|
||||
# 标题标签
|
||||
|
||||
标题使用`<h1>`至`<h6>`标签进行定义。`<h1>`定义最大的标题,`<h6>`定义最小的标题。具有align属性,属性值可以是:left、center、right。
|
||||
|
||||
代码举例:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>H1:学前沿IT,到英格科技!</h1>
|
||||
<h2>H3:学前沿IT,到英格科技!</h2>
|
||||
<h3>H3:学前沿IT,到英格科技!</h3>
|
||||
<h4>H4:学前沿IT,到英格科技!</h4>
|
||||
<h5>H5:学前沿IT,到英格科技!</h5>
|
||||
<h6>H6:学前沿IT,到英格科技!</h6>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
|
||||
# HTML 注释
|
||||
|
||||
HTML 注释的格式如下:
|
||||
|
||||
```html
|
||||
<!-- 我是 html 注释 -->
|
||||
```
|
||||
|
||||
|
||||
|
||||
# 段落标签`<p>`
|
||||
|
||||
段落,是英语“paragraph“缩写。
|
||||
|
||||
**作用**:可以把 HTML 文档分割为若干段落。在网页中如果要把文字有条理地显示出来,离不开段落标签。就如同我们平常写文章一样,整个网页也可以分为若干个段落。
|
||||
|
||||
代码举例:
|
||||
|
||||
```html
|
||||
<p>This is a paragraph</p>
|
||||
<p>This is another paragraph</p>
|
||||
```
|
||||
|
||||
属性:
|
||||
|
||||
- `align="属性值"`:对齐方式。属性值包括left center right。
|
||||
|
||||
HTML标签是分等级的,HTML将所有的标签分为两种:
|
||||
|
||||
- **文本级标签**:p、span、a、b、i、u、em。文本级标签里只能放**文字、图片、表单元素**。(a标签里不能放a和input)
|
||||
|
||||
- **容器级标签**:div、h系列、li、dt、dd。容器级标签里可以放置任何东西。
|
||||
|
||||
从学习p的第一天开始,就要牢牢记住:**p标签是一个文本级标签,p里面只能放文字、图片、表单元素**。其他的一律不能放。
|
||||
|
||||
错误写法:(尝试把 h 放到 p 里)
|
||||
|
||||
```html
|
||||
<p>
|
||||
我是一个小段落
|
||||
<h1>我是一级标题</h1>
|
||||
</p>
|
||||
```
|
||||
|
||||
浏览器不允许你这么做,我们使用Chrome的F12审查元素发现,浏览器自己把p封闭掉了,不让你去包裹h1。
|
||||
|
||||
PS:Chrome浏览器是HTML5支持度最好的浏览器。提供了非常好的开发工具,非常适合我们开发人员使用。审查元素功能的快捷键是F12。
|
||||
|
||||
# 水平线标签`<hr />`
|
||||
|
||||
> horizontal 单词的发音:[ˌhɒrɪˈzɒntl]。
|
||||
|
||||
水平分隔线(horizontal rule)可以在视觉上将文档分隔成各个部分。在网页中常常看到一些水平线将段落与段落之间隔开,使得文档结构清晰,层次分明。
|
||||
|
||||
代码举例:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>自古情深留不住</p>
|
||||
<hr />
|
||||
<p>总是套路得人心</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
属性介绍:
|
||||
|
||||
- `align="属性值"`:设定线条置放位置。属性值可选择:left right center。
|
||||
- `size="2" `:设定线条粗细。以像素为单位,内定为2。
|
||||
- `width="500"`或`width="70%"`:设定线条长度。可以是绝对值(单位是像素)或相对值。如果设置为相对值的话,内定为100%。
|
||||
- `color="#0000FF"`:设置线条颜色。
|
||||
- `noshade`:不要阴影,即设定线条为平面显示。若没有这个属性则表明线条具阴影或立体。
|
||||
|
||||
# 换行标签`<br />`
|
||||
|
||||
如果希望某段文本强制换行显示,就需要使用换行标签。
|
||||
|
||||
```html
|
||||
This <br/> is a para<br/>graph with line breaks
|
||||
```
|
||||
|
||||
# `<div>`和`<span>`标签
|
||||
|
||||
div和span是非常重要的标签,div的语义是division“分割”; span的语义就是span“范围、跨度”。想必你应该听说过“div + css”布局。
|
||||
|
||||
## div和span的介绍
|
||||
|
||||
- **div标签**:可以把标签中的内容分割为独立的区块。必须单独占据一行。
|
||||
|
||||
- **span标签**:和div的作用一致,但不换行。
|
||||
|
||||
div标签的属性:
|
||||
|
||||
- `align="属性值"`:设置块儿的位置。属性值可选择:left、right、 center。
|
||||
|
||||
## div和span的区别
|
||||
|
||||
`<span>`和`<div>`唯一的区别在于:`<span>`是不换行的,而`<div>`是换行的。
|
||||
|
||||
如果单独在网页中插入这两个元素,不会对页面产生任何的影响。这两个元素是专门为定义CSS样式而生的。或者说,DIV+CSS来实现各种样式。
|
||||
|
||||
div在浏览器中,默认是不会增加任何的效果的,但是语义变了,div中的所有元素是一个小区域。
|
||||
div标签是一个**容器级**标签,里面什么都能放,甚至可以放div自己。
|
||||
|
||||
span也是表达“小区域、小跨度”的标签,但只是一个**文本级**的标签。
|
||||
就是说,span里面只能放置文字、图片、表单元素。 span里面不能放p、h、ul、dl、ol、div。
|
||||
|
||||
span举例:
|
||||
|
||||
```html
|
||||
<p>
|
||||
简介简介简介简介简介简介简介简介
|
||||
<span>
|
||||
<a href="">详细信息</a>
|
||||
<a href="">购买</a>
|
||||
</span>
|
||||
</p>
|
||||
```
|
||||
|
||||
div举例:
|
||||
|
||||
```html
|
||||
<div class="header">
|
||||
<div class="logo"></div>
|
||||
<div class="nav"></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="guanggao"></div>
|
||||
<div class="dongxi"></div>
|
||||
</div>
|
||||
<div class="footer"></div>
|
||||
```
|
||||
|
||||
这种模式叫做“**div+css**”:**div标签负责布局、结构、分块,css负责样式**。
|
||||
|
||||
# 内容居中标签 `<center>`
|
||||
|
||||
此时center代表是一个标签,而不是一个属性值了。只要是在这个标签里面的内容,都会居于浏览器的中间。
|
||||
|
||||
到了HTML5里面,center标签不建议使用,建议使用css布局来实现。
|
||||
|
||||
# 预定义(预格式化)标签`<pre>`
|
||||
|
||||
含义:将保留标签内部所有的空白字符(空格、换行符),原封不动地输出结果(告诉浏览器不要忽略空格和空行)。
|
||||
|
||||
说明:真正排网页过程中,`<pre>`标签几乎用不着。
|
||||
|
||||
# 字体标签
|
||||
|
||||
## 特殊字符(转义字符)
|
||||
|
||||
- ` `:空格 (non-breaking spacing,不断打空格)
|
||||
- `<`:小于号(less than)
|
||||
- `>`:大于号(greater than)
|
||||
- `&`:符号`&`
|
||||
- `"`:双引号
|
||||
- `'`:单引号
|
||||
- `©`:版权`©`
|
||||
- `™`:商标`™`
|
||||
- `绐`:文字`绐`。其实,`#32464`是汉字`绐`的unicode编码。
|
||||
|
||||
要求背诵的特殊字符有:` `、`<`、`>`、`©`。
|
||||
|
||||
比如说,你想把`<p>`作为一个文本在页面上显示,直接写`<p>`是肯定不行的,因为这代表的是一个段落标签,所以这里需要用到**转义字符**。应该这么写:
|
||||
|
||||
```html
|
||||
这是一个HTML语言的<p>标签
|
||||
```
|
||||
|
||||
字符代码查询表
|
||||
|
||||
|
||||
|
||||
| 特殊字符 | 描述 | 字符的代码 |
|
||||
| :------- | :------------- | :--------- |
|
||||
| | 空格符 | ` ` |
|
||||
| < | 小于号 | `<` |
|
||||
| > | 大于号 | `>` |
|
||||
| & | 和号 | `&` |
|
||||
| ¥ | 人民币 | `¥` |
|
||||
| © | 版权 | `©` |
|
||||
| ® | 注册商标 | `®` |
|
||||
| ° | 摄氏度 | `°` |
|
||||
| ± | 正负号 | `±` |
|
||||
| × | 乘号 | `×` |
|
||||
| ÷ | 除号 | `÷` |
|
||||
| ² | 平方2(上标2) | `²` |
|
||||
| ³ | 立方3(上标3) | `³` |
|
||||
|
||||
## 下划线、中划线、斜体
|
||||
|
||||
- `<u>`:下划线标记
|
||||
|
||||
- `<s>`或`<del>`:中划线标记(删除线)
|
||||
|
||||
- `<i>`或`<em>`:斜体标记
|
||||
|
||||
## 字体标签`<font>`(已废弃)
|
||||
|
||||
属性:
|
||||
|
||||
- `color="红色"`或`color="#ff00cc"`或`color="new rgb(0,0,255)"`:设置字体颜色。
|
||||
设置方式:单词 \ #ff00cc \ rgb(0,0,255)
|
||||
|
||||
- `size`:设置字体大小。 取值范围只能是:1至7。取值时,如果取值大于7那就按照7来算,如果取值小于1那就按照1来算。如果想要更大的字体,那就只能通过css样式来解决。
|
||||
|
||||
- `face="微软雅黑"`:设置字体类型。
|
||||
|
||||
举例:
|
||||
|
||||
```html
|
||||
<font face="微软雅黑" color="#FF0000" size="10">vae</font>
|
||||
```
|
||||
|
||||
## 上标`<sup>` 下标`<sub>`
|
||||
|
||||
上小标这两个标签容易混淆,怎么记呢?这样记:`b`的意思是`bottom:底部`
|
||||
举例:
|
||||
|
||||
```html
|
||||
O<sup>2</sup> 5<sub>3</sub>
|
||||
```
|
||||
|
||||
# 超链接
|
||||
|
||||
## 外部链接:链接到外部文件
|
||||
|
||||
举例:
|
||||
|
||||
```html
|
||||
<a href="02页面.html">点击进入另外一个文件</a>
|
||||
```
|
||||
|
||||
a是英语`anchor`“锚”的意思,就好像这个页面往另一个页面扔出了一个锚。是一个文本级的标签。
|
||||
|
||||
href(hypertext reference):超文本地址。读作“喝瑞夫”,不要读作“喝夫”。
|
||||
|
||||
当然,我们也可以直接点进链接,访问一个网址。举例如下:
|
||||
|
||||
```html
|
||||
<a href="http://www.baidu.com" target="_blank">点我点我</a>
|
||||
```
|
||||
|
||||
## 锚链接
|
||||
|
||||
**锚链接**:给超链接起一个名字,作用是**在本页面或者其他页面的的不同位置进行跳转**。比如说,在网页底部有一个向上箭头,点击箭头后回到顶部,这个就可以利用锚链接。
|
||||
|
||||
首先我们要创建一个**锚点**,也就是说,使用`name`属性或者`id`属性给那个特定的位置起个名字。效果如下:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<a href="" id="top">顶部</a>
|
||||
<pre>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
<a href="#top">回到顶部</a>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
上图中解释:
|
||||
|
||||
第11行代码表示,顶部这个锚的名字叫做name1。
|
||||
然后在底部设置超链接,点击时将回到顶部(此时,网页中的url的末尾也出现了`#name1`)。注意**上图中红框部分的`#`号不要忘记了**,表示跳到名为name1的特定位置,这是规定。如果少了`#`号,点击之后,就会跳到name1这个文件或者name1这个文件夹中去。
|
||||
|
||||
如果我们将上图中的第28行代码写成:
|
||||
|
||||
```html
|
||||
<a href="a.html#name1">回到顶部</a>
|
||||
```
|
||||
|
||||
那就表示,点击之后,跳转到`a.html`页面的`name1锚点`中去。
|
||||
|
||||
说明:name属性是HTML4.0以前使用的,id属性是HTML4.0后才开始使用。为了向前兼容,因此,name和id这两个属性都要写上,并且值是一样的。
|
||||
|
||||
## 邮件链接
|
||||
|
||||
代码举例:
|
||||
|
||||
```html
|
||||
<a href="mailto:xxx@163.com">点击进入我的邮箱</a>
|
||||
```
|
||||
|
||||
效果:点击之后,会弹出outlook,作用不大。
|
||||
|
||||
## 超链接的属性
|
||||
|
||||
- `href`:目标URL
|
||||
- `title`:悬停文本。
|
||||
- `name`:主要用于设置一个锚点的名称。
|
||||
- `target`:告诉浏览器用什么方式来打开目标页面。`target`属性有以下几个值:
|
||||
- `_self`:在同一个网页中显示(默认值)
|
||||
- `_blank`:**在新的窗口中打开**。
|
||||
- `_parent`:在父窗口中显示
|
||||
- `_top`:在顶级窗口中显示
|
||||
|
||||
|
||||
`title`属性举例:
|
||||
|
||||
```html
|
||||
<a href="" title="点我有好看的">我是超链接</a>
|
||||
```
|
||||
|
||||
效果如下:
|
||||
|
||||

|
||||
|
||||
`target`属性举例:
|
||||
|
||||
```html
|
||||
<a href="1.html" title="悬停文本" target="_blank">链接的内容</a>
|
||||
```
|
||||
|
||||
blank就是“空白”的意思,就表示新建一个空白窗口。为啥有一个_ ,就是规定,无需解释。
|
||||
也就是说,如果不写`target=”_blank”`那么就是在相同的标签页打开,如果写了`target=”_blank”`,就是在新的空白标签页中打开。
|
||||
|
||||
## 案例1
|
||||
|
||||
分清楚img和a标签的各自的属性
|
||||
|
||||
区别如下:
|
||||
|
||||
```html
|
||||
<img src="1.jpg" />
|
||||
<a href="1.html"></a>
|
||||
```
|
||||
|
||||
## 案例2
|
||||
|
||||
a是一个文本级的标签
|
||||
|
||||
比如一个段落中的所有文字都能够被点击,那么应该是p包裹a:
|
||||
|
||||
```html
|
||||
<p>
|
||||
<a href="">段落段落段落段落段落段落</a>
|
||||
</p>
|
||||
```
|
||||
|
||||
而不是a包裹p:
|
||||
|
||||
```html
|
||||
<a href="">
|
||||
<p>
|
||||
段落段落段落段落段落段落
|
||||
</p>
|
||||
</a>
|
||||
```
|
||||
|
||||
a的语义要小于p,a就是可以当做文本来处理,所以p里面相当于放的就是纯文字。
|
||||
|
||||
# img标签介绍
|
||||
|
||||
## 介绍
|
||||
|
||||
img: 英文全称 image(图像),代表的是一张图片。
|
||||
|
||||
如果要想在网页中显示图像,就可以使用img 标签,它是一个单标签。语法如下:
|
||||
|
||||
```html
|
||||
<img src="图片的URL" />
|
||||
```
|
||||
|
||||
## 能插入的图片类型
|
||||
|
||||
- 能够插入的图片类型是:jpg(jpeg)、gif、png、bmp等。
|
||||
|
||||
- 不能往网页中插入的图片格式是:psd、ai等。
|
||||
|
||||
HTML页面不是直接插入图片,而是插入图片的引用地址,所以要先把图片上传到服务器上。
|
||||
|
||||
## img标签的`src`属性
|
||||
|
||||
这里涉及到图片的一个属性:
|
||||
|
||||
- `src`属性:指图片的路径。英文名称 source。
|
||||
|
||||
在写**图片的路径**时,有两种写法:相对路径、绝对路径
|
||||
|
||||
### 图片的相对路径
|
||||
|
||||
相对当前页面所在的路径。两个标记 `.` 和 `..` 分表代表当前目录和上一层目录。
|
||||
|
||||
举例1:
|
||||
|
||||
```html
|
||||
<!-- 当前目录中的图片 -->
|
||||
<img src="2.jpg">
|
||||
<img src=".\2.jpg">
|
||||
|
||||
<!-- 上一级目录中的图片 -->
|
||||
<img src="..\2.jpg">
|
||||
```
|
||||
|
||||
相对路径不会出现这种情况:
|
||||
|
||||
```html
|
||||
aaa/../bbb/1.jpg
|
||||
```
|
||||
|
||||
`../`要么不写,要么就写在开头。
|
||||
|
||||
举例2:
|
||||
|
||||
```html
|
||||
<img src="images/1.jpg">
|
||||
```
|
||||
|
||||
上方代码的意思是说,当前html页面有一个并列的文件夹`images`,在文件夹`images`中存放了一张图片`1.jpg`
|
||||
效果:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<img width="400px" src="images/1.jpeg" alt="">
|
||||
</body>
|
||||
```
|
||||
|
||||

|
||||
|
||||
相对路径的面试题。现有如下文件层级图:
|
||||
|
||||

|
||||
|
||||
问题:如果想在index.html中插入1.png,那么对应的img语句是?
|
||||
|
||||
分析:
|
||||
|
||||
现在document是最大的文件夹,里面有两个文件夹work和photo。work中又有一个文件夹叫做myweb。myweb文件夹里面有index.html。 所以index.html在myweb文件夹里面,上一级就是work文件夹,上两级就是document文件夹。通过document文件夹当做一个中转站,进入photo文件夹,看到了1.png。
|
||||
|
||||
答案:
|
||||
|
||||
```html
|
||||
<img src="../../photo/1.png" />
|
||||
```
|
||||
|
||||
### 图片的绝对路径
|
||||
|
||||
绝对路径包括以下两种:
|
||||
|
||||
(1)以盘符开始的绝对路径。举例:
|
||||
|
||||
```html
|
||||
<img src="C:\Users\simidaxu\Desktop\html\images\1.jpg">
|
||||
```
|
||||
|
||||
(2)网络路径。举例:
|
||||
|
||||
```html
|
||||
<img src="https://iproute.cn/html/assets/img/hiden.png">
|
||||
```
|
||||
|
||||
### 相对路径和绝对路径的总结
|
||||
|
||||
相对路径的好处:站点不管拷贝到哪里,文件和图片的相对路径关系都是不变的。相对路径使用有一个前提,就是网页文件和你的图片,必须在一个服务器上。
|
||||
|
||||
问题:我的网页在C盘,图片却在D盘,能不能插入呢?
|
||||
|
||||
答案: 用相对路径不能,用绝对路径也不能。
|
||||
|
||||
注意:可以使用file://来插入,但是这种方法,没有任何意义!因为服务器上没有所谓c盘、d盘。
|
||||
|
||||
下面的方法是行的,但是没有任何工程上的意义,这是因为服务器没有盘符,linux系统没有盘符:
|
||||
|
||||
```html
|
||||
<img src="file://C:\Users\simidaxu\Pictures\明星\1.jpg" alt="" />
|
||||
```
|
||||
|
||||
**总结一下**:
|
||||
|
||||
无论是在 a 标签还是 img 标签上,如果要用路径。只有两种路径能用,就是相对路径和绝对路径:
|
||||
|
||||
- 相对路径从自己出发,找到别人。
|
||||
|
||||
- 绝对路径,就是`http://`或者`https://`开头的路径。
|
||||
|
||||
- 绝对不允许使用`file://`开头的文件,这个是完全错误的!
|
||||
BIN
project12/01.初识HTML/2015-10-01-cnblogs_html_18.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
project12/01.初识HTML/20151001_19.jpg
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
project12/01.初识HTML/20170630_1133.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
project12/01.初识HTML/20170630_1415.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
project12/01.初识HTML/image-20241215153322926.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
project12/01.初识HTML/image-20241217102544576.png
Normal file
|
After Width: | Height: | Size: 199 KiB |
BIN
project12/01.初识HTML/image-20241217102937417.png
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
project12/01.初识HTML/image-20241217104459256.png
Normal file
|
After Width: | Height: | Size: 680 KiB |
BIN
project12/01.初识HTML/image-20241217104514770.png
Normal file
|
After Width: | Height: | Size: 555 KiB |
BIN
project12/01.初识HTML/image-20241217104528260.png
Normal file
|
After Width: | Height: | Size: 631 KiB |
366
project12/02.[任务书]table标签的使用.md
Normal file
@@ -0,0 +1,366 @@
|
||||
# table标签的使用
|
||||
|
||||
## 需求
|
||||
|
||||
- 在网页中表格是经常见到的数据呈现形式
|
||||
- 在网页中获取用户的输入也是经常会使用的
|
||||
- 本次的任务就是大家通过自学的方式掌握`table`标签和`input` 标签的使用
|
||||
- **最终完成一个信息收集网页的开发**
|
||||
|
||||
## 参考代码
|
||||
|
||||
- 效果
|
||||
|
||||

|
||||
|
||||
- 代码
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<center>
|
||||
<h1>大学生信息收集</h1>
|
||||
</center>
|
||||
<table border="1px" cellspacing="0" cellpadding="0" align="center">
|
||||
<tr height="50px" align="center">
|
||||
<td width="100px">姓名</td>
|
||||
<td width="150px"><input type="text"></td>
|
||||
<td width="100px">性别</td>
|
||||
<td width="150px"><input type="text"></td>
|
||||
<td width="100px" rowspan="2">照片</td>
|
||||
</tr>
|
||||
<tr height="50px" align="center">
|
||||
<td width="100px">年级</td>
|
||||
<td width="150px"><input type="text"></td>
|
||||
<td width="100px">专业</td>
|
||||
<td width="150px"><input type="text"></td>
|
||||
</tr>
|
||||
<tr height="50px" align="center">
|
||||
<td>手机号码</td>
|
||||
<td colspan="4"><input type="text"></td>
|
||||
</tr>
|
||||
<tr height="50px" align="center">
|
||||
<td>联系地址</td>
|
||||
<td colspan="4"><input type="text"></td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td colspan="5"><input type="submit"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
|
||||
><span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业12.1提交的内容</span>
|
||||
>
|
||||
>- 学习表格和表单,理解程序的运行逻辑
|
||||
>- 程序运行成功的截图,单独发送给组长
|
||||
|
||||
# 表格
|
||||
|
||||
## 表格基本结构
|
||||
|
||||
一个基本的HTML表格由以下元素组成:
|
||||
|
||||
- `<table>`:定义表格的开始。
|
||||
- `<tr>`:定义表格中的行。
|
||||
- `<td>`:定义表格中的单元格。
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<td>序号</td>
|
||||
<td>姓名</td>
|
||||
<td>性别</td>
|
||||
<td>爱好</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>张三</td>
|
||||
<td>男</td>
|
||||
<td>看书</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
## 表格的属性
|
||||
|
||||
- 宽度:width
|
||||
- 高度:height
|
||||
- 边框:border
|
||||
- 边框颜色:bordercolor
|
||||
- 背景颜色:bgcolor
|
||||
- 水平对齐:align=“left或right或center”
|
||||
- cellspacing=“单元格与单元格之间的间距”
|
||||
- cellpadding=“单元格与内容之间的空隙”
|
||||
|
||||
为了显示表格的框线,可以在`table`标签中加入如下属性
|
||||
|
||||
```html
|
||||
<table border="1px">
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
去除表格和单元格之间的空隙
|
||||
|
||||
```html
|
||||
<table border="1px" cellspacing="0">
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
使表格水平居中
|
||||
|
||||
```html
|
||||
<table border="1px" cellspacing="0" align="center">
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
## 行的属性
|
||||
|
||||
- 高度 height
|
||||
|
||||
- 背景颜色 bgcolor
|
||||
|
||||
- 文字水平对齐 align=“left 或 right 或 center”
|
||||
|
||||
- 文字垂直对齐 valign=“top 或 middle 或 bottom”
|
||||
|
||||
- 调整表格的行样式,修改第一行的背景色,并且设置文字水平对齐
|
||||
|
||||
```html
|
||||
<tr height="30px" bgcolor="skyblue" align="center">
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
## 列的属性
|
||||
|
||||
- 宽度 width
|
||||
- 高度 height
|
||||
- 背景颜色 bgcolor
|
||||
- 文字水平对齐 align=“left或right或center”
|
||||
- 文字垂直对齐 valign=“top或middle或bottom”
|
||||
|
||||
- 调整表格的样式,将列的宽度进行适当的调整,注意!列的宽度只需要改动第一列即可。
|
||||
|
||||
```html
|
||||
<table border="1px" cellspacing="0" align="center">
|
||||
<tr height="30px" bgcolor="skyblue" align="center">
|
||||
<td width="50px">序号</td>
|
||||
<td width="100px">姓名</td>
|
||||
<td width="100px">性别</td>
|
||||
<td width="100px">爱好</td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td>1</td>
|
||||
<td>张三</td>
|
||||
<td>男</td>
|
||||
<td>看书</td>
|
||||
</tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
# 输入标签
|
||||
|
||||
`<input>`:输入标签用于接收用户输入。
|
||||
|
||||
```html
|
||||
<input type="text" value="内容" >
|
||||
```
|
||||
|
||||
**属性:**
|
||||
|
||||
- **`type="属性值"`**:文本类型。属性值可以是:
|
||||
- `text`(默认)
|
||||
- `password`:密码类型
|
||||
- `radio`:单选按钮,名字相同的按钮作为一组进行单选(单选按钮,天生是不能互斥的,如果想互斥,必须要有相同的name属性。name就是“名字”。
|
||||
)。非常像以前的收音机,按下去一个按钮,其他的就抬起来了。所以叫做radio。
|
||||
- `checkbox`:多选按钮,**name 属性值相同的按钮**作为一组进行选择。
|
||||
- `checked`:将单选按钮或多选按钮默认处于选中状态。当`<input>`标签设置为`type="radio"`或者`type=checkbox`时,可以用这个属性。属性值也是checked,可以省略。
|
||||
- `hidden`:隐藏框,在表单中包含不希望用户看见的信息
|
||||
- `button`:普通按钮,结合js代码进行使用。
|
||||
- `submit`:提交按钮,传送当前表单的数据给服务器或其他程序处理。这个按钮不需要写value自动就会有“提交”文字。这个按钮真的有提交功能。点击按钮后,这个表单就会被提交到form标签的action属性中指定的那个页面中去。
|
||||
- `reset`:重置按钮,清空当前表单的内容,并设置为最初的默认值
|
||||
- `image`:图片按钮,和提交按钮的功能完全一致,只不过图片按钮可以显示图片。
|
||||
- `file`:文件选择框。
|
||||
提示:如果要限制上传文件的类型,需要配合JS来实现验证。对上传文件的安全检查:一是扩展名的检查,二是文件数据内容的检查。
|
||||
|
||||
- **`value="内容"`**:文本框里的默认内容(已经被填好了的)
|
||||
|
||||
- `size="50"`:表示文本框内可以显示**五十个字符**。一个英文或一个中文都算一个字符。
|
||||
注意**size属性值的单位不是像素哦**。
|
||||
|
||||
- `readonly`:文本框只读,不能编辑。因为它的属性值也是readonly,所以属性值可以不写。
|
||||
用了这个属性之后,在google浏览器中,光标点不进去;在IE浏览器中,光标可以点进去,但是文字不能编辑。
|
||||
|
||||
- `disabled`:文本框只读,不能编辑,光标点不进去。属性值可以不写。
|
||||
|
||||
> 备注:HTML5中,input的类型又增加了很多(比如date、color,我们会在 html5 中讲到)。
|
||||
|
||||
**举例**:
|
||||
|
||||
```html
|
||||
<form>
|
||||
姓名:<input value="张三"><br>
|
||||
昵称:<input value="三三" readonly=""><br>
|
||||
名字:<input type="text" value="name" disabled=""><br>
|
||||
密码:<input type="password" value="pwd" size="50"><br>
|
||||
性别:
|
||||
<input type="radio" name="gender" id="radio1" value="male" checked="">男
|
||||
<input type="radio" name="gender" id="radio2" value="female">女<br>
|
||||
爱好:
|
||||
<input type="checkbox" name="love" value="eat">吃饭
|
||||
<input type="checkbox" name="love" value="sleep">睡觉
|
||||
<input type="checkbox" name="love" value="bat">看书
|
||||
</form>
|
||||
```
|
||||
|
||||
效果:
|
||||
|
||||

|
||||
|
||||
注意,多个个单选框的input标签中,name 的属性值可以相同,但是 **id 的属性值必须是唯一的**。我们知道,html的标签中,id的属性值是唯一的。
|
||||
|
||||
**四种按钮的举例**:
|
||||
|
||||
```html
|
||||
<form>
|
||||
<input type="button" value="普通按钮"><br>
|
||||
<input type="submit" value="提交按钮"><br>
|
||||
<input type="reset" value="重置按钮"><br>
|
||||
<input type="image" value="图片按钮1"><br>
|
||||
<input type="image" src="images/1.jpeg" width="300" value="图片按钮2"><br>
|
||||
<input type="file" value="文件选择框">
|
||||
</form>
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
`<datalist>` 数据列表
|
||||
|
||||
```html
|
||||
<input type="text" list="myData">
|
||||
<datalist id="myData">
|
||||
<option>本科</option>
|
||||
<option>研究生</option>
|
||||
<option>不明</option>
|
||||
</datalist>
|
||||
```
|
||||
|
||||
上方代码中,input里的list属性和 datalist 进行了绑定。
|
||||
|
||||
效果
|
||||
|
||||

|
||||
|
||||
### `<select>`:下拉列表标签
|
||||
|
||||
`<select>`标签里面的每一项用`<option>`表示。select就是“选择”,option“选项”。
|
||||
|
||||
select标签和ul、ol、dl一样,都是组标签。
|
||||
|
||||
**`<select>`标签的属性:**
|
||||
|
||||
- `multiple`:可以对下拉列表中的选项进行多选。属性值为 multiple,也可以没有属性值。也就是说,既可以写成 `multiple=""`,也可以写成`multiple="multiple"`。
|
||||
- `size="3"`:如果属性值大于1,则列表为滚动视图。默认属性值为1,即下拉视图。
|
||||
|
||||
**`<option>`标签的属性:**
|
||||
|
||||
- `selected`:预选中。没有属性值。
|
||||
|
||||
举例:
|
||||
|
||||
```html
|
||||
<form>
|
||||
<select>
|
||||
<option>小学</option>
|
||||
<option>初中</option>
|
||||
<option>高中</option>
|
||||
<option>大学</option>
|
||||
<option selected="">研究生</option>
|
||||
</select>
|
||||
<br><br><br>
|
||||
|
||||
<select size="3">
|
||||
<option>小学</option>
|
||||
<option>初中</option>
|
||||
<option>高中</option>
|
||||
<option>大学</option>
|
||||
<option>研究生</option>
|
||||
</select>
|
||||
<br><br><br>
|
||||
|
||||
<select multiple="">
|
||||
<option>小学</option>
|
||||
<option>初中</option>
|
||||
<option selected="">高中</option>
|
||||
<option selected="">大学</option>
|
||||
<option>研究生</option>
|
||||
</select>
|
||||
<br><br><br>
|
||||
|
||||
</form>
|
||||
```
|
||||
|
||||
效果:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
project12/02.[任务书]table标签的使用/image-20241217154445212.png
Normal file
|
After Width: | Height: | Size: 217 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217155117054.png
Normal file
|
After Width: | Height: | Size: 219 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217155340313.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217155423128.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217155606535.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217155702225.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217160036271.png
Normal file
|
After Width: | Height: | Size: 220 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217160630428.png
Normal file
|
After Width: | Height: | Size: 220 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217161358523.png
Normal file
|
After Width: | Height: | Size: 241 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217161534542.png
Normal file
|
After Width: | Height: | Size: 515 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217161656141.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217164803505.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217165043639.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217165115882.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
project12/02.[任务书]table标签的使用/image-20241217165806798.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
333
project13/01.CSS基础.md
Normal file
@@ -0,0 +1,333 @@
|
||||
# CSS
|
||||
|
||||
css主要用于定义页面效果
|
||||
|
||||
所有的页面效果属性:https://main.eagleslab.com/css3/
|
||||
|
||||
## 应用方式
|
||||
|
||||
- 行内样式
|
||||
- 将css属性,直接写在标签style属性中
|
||||
- 只适用于简单的样式,如果比较复杂,就会难以维护
|
||||
|
||||
```html
|
||||
<h1 style="color: skyblue;text-shadow: 1px 1px 2px lightskyblue;">欢迎登录</h1>
|
||||
<!-- color属性适用于修改文字颜色 -->
|
||||
<!-- text-shadow属性可以用于给文字添加阴影效果 -->
|
||||
```
|
||||
|
||||

|
||||
|
||||
- 内部样式
|
||||
- 在head标签中写上style标签,并且在标签内写上css
|
||||
- 必须要有选择器,用于选择生效的范围
|
||||
- 标签选择器,直接写标签名
|
||||
|
||||
```html
|
||||
<style>
|
||||
body {
|
||||
/* 修改背景 */
|
||||
background: url("images/1.jpeg");
|
||||
/* 背景图 */
|
||||
background-position: center 0;
|
||||
/* 背景水平居中,后面的0表示上下不动 */
|
||||
background-repeat: no-repeat;
|
||||
/* 背景图不要重复 */
|
||||
background-size: cover;
|
||||
/* 背景图大小自动铺满屏幕 */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||

|
||||
|
||||
- id选择器
|
||||
- 在标签中可以加上id属性,用于标识唯一的元素
|
||||
- 需要在对应的标签加上id属性
|
||||
- 用#在id前作为选择器
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
body {
|
||||
/* 修改背景 */
|
||||
background: url("images/1.jpeg");
|
||||
/* 背景图 */
|
||||
background-position: center 0;
|
||||
/* 背景水平居中,后面的0表示上下不动 */
|
||||
background-repeat: no-repeat;
|
||||
/* 背景图不要重复 */
|
||||
background-size: cover;
|
||||
/* 背景图大小自动铺满屏幕 */
|
||||
}
|
||||
|
||||
#login_btn {
|
||||
color: purple;
|
||||
background: linear-gradient(45deg, red, green, blue, white, orange, yellow);
|
||||
/* 生成渐变色 */
|
||||
border: 2px solid orange;
|
||||
/* 边框2px宽,实线,橙色 */
|
||||
border-radius: 10px;
|
||||
/* 边角圆度10px */
|
||||
padding: 10px 20px;
|
||||
/* 内边距,可以看到背景被撑大 */
|
||||
text-shadow: 1px 1px 2px gold;
|
||||
/* 文字的阴影效果,上下1px 左右1px 模糊程度2px 颜色gold */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form action="">
|
||||
<h1 style="color: skyblue;text-shadow: 1px 1px 2px lightskyblue;">欢迎登录</h1>
|
||||
<input type="text" placeholder="用户名">
|
||||
<input type="password" placeholder="密码">
|
||||
<input type="submit" id="login_btn" value="登录">
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||

|
||||
|
||||
- class选择器
|
||||
- 需要在对应的标签加上class属性
|
||||
- 在前面加上.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
body {
|
||||
/* 修改背景 */
|
||||
background: url("images/1.jpeg");
|
||||
/* 背景图 */
|
||||
background-position: center 0;
|
||||
/* 背景水平居中,后面的0表示上下不动 */
|
||||
background-repeat: no-repeat;
|
||||
/* 背景图不要重复 */
|
||||
background-size: cover;
|
||||
/* 背景图大小自动铺满屏幕 */
|
||||
}
|
||||
|
||||
#login_btn {
|
||||
color: purple;
|
||||
background: linear-gradient(45deg, red, green, blue, white, orange, yellow);
|
||||
/* 生成渐变色 */
|
||||
border: 2px solid orange;
|
||||
/* 边框2px宽,实线,橙色 */
|
||||
border-radius: 10px;
|
||||
/* 边角圆度10px */
|
||||
padding: 10px 20px;
|
||||
/* 内边距,可以看到背景被撑大 */
|
||||
text-shadow: 1px 1px 2px gold;
|
||||
/* 文字的阴影效果,上下1px 左右1px 模糊程度2px 颜色gold */
|
||||
}
|
||||
|
||||
.input_text {
|
||||
background: none;
|
||||
/* 去除背景 */
|
||||
border: 2px solid orange;
|
||||
padding: 15px 20px;
|
||||
margin: 10px auto;
|
||||
/* 外边距,上下10px,左右居中自动调整 */
|
||||
width: 180px;
|
||||
/* 宽度 */
|
||||
text-align: center;
|
||||
/* 文字居中 */
|
||||
outline: none;
|
||||
/* 外部的线,只有文本框被选择的时候出现 */
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form action="">
|
||||
<h1 style="color: skyblue;text-shadow: 1px 1px 2px lightskyblue;">欢迎登录</h1>
|
||||
<input type="text" class="input_text" placeholder="用户名">
|
||||
<input type="password" class="input_text" placeholder="密码">
|
||||
<input type="submit" id="login_btn" value="登录">
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 布局
|
||||
|
||||
- div标签
|
||||
- 本身没有任何的效果,用于将多个标签组合
|
||||
- 往往需要搭配id、class选择器和css一起使用
|
||||
- 会占据一整行
|
||||
- span标签
|
||||
- 本身没有任何的效果,用于将多个标签组合
|
||||
- 往往需要搭配id、class选择器和css一起使用
|
||||
- 不会占据一整行
|
||||
|
||||
如果想要将一些元素作为一个整体进行布局,可以加上div
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<style>
|
||||
body {
|
||||
/* 修改背景 */
|
||||
background: url("images/1.jpeg");
|
||||
/* 背景图 */
|
||||
background-position: center 0;
|
||||
/* 背景水平居中,后面的0表示上下不动 */
|
||||
background-repeat: no-repeat;
|
||||
/* 背景图不要重复 */
|
||||
background-size: cover;
|
||||
/* 背景图大小自动铺满屏幕 */
|
||||
}
|
||||
|
||||
#login_btn {
|
||||
color: purple;
|
||||
background: linear-gradient(45deg, red, green, blue, white, orange, yellow);
|
||||
/* 生成渐变色 */
|
||||
border: 2px solid orange;
|
||||
/* 边框2px宽,实线,橙色 */
|
||||
border-radius: 10px;
|
||||
/* 边角圆度10px */
|
||||
padding: 10px 20px;
|
||||
/* 内边距,可以看到背景被撑大 */
|
||||
text-shadow: 1px 1px 2px gold;
|
||||
/* 文字的阴影效果,上下1px 左右1px 模糊程度2px 颜色gold */
|
||||
}
|
||||
|
||||
.input_text {
|
||||
background: none;
|
||||
/* 去除背景 */
|
||||
border: 2px solid orange;
|
||||
padding: 15px 20px;
|
||||
margin: 10px auto;
|
||||
/* 外边距,上下10px,左右居中自动调整 */
|
||||
width: 180px;
|
||||
/* 宽度 */
|
||||
text-align: center;
|
||||
/* 文字居中 */
|
||||
outline: none;
|
||||
/* 外部的线,只有文本框被选择的时候出现 */
|
||||
color: white;
|
||||
display: block;
|
||||
/* 改inline模式为block */
|
||||
}
|
||||
|
||||
.input_text::placeholder {
|
||||
/* input框中的提示文字样式 */
|
||||
color: white;
|
||||
}
|
||||
|
||||
.box {
|
||||
position: absolute;
|
||||
/* 修改基于窗口的绝对定位 */
|
||||
left: 50%;
|
||||
/* 离窗口左边50% */
|
||||
top: 50%;
|
||||
/* 离窗口顶部50% */
|
||||
transform: translate(-50%, -50%);
|
||||
/* 将元素调整到正中间 */
|
||||
text-align: center;
|
||||
/* 内部的文字居中 */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<form action="">
|
||||
<h1 style="color: skyblue;text-shadow: 1px 1px 2px lightskyblue;">欢迎登录</h1>
|
||||
<input type="text" class="input_text" placeholder="用户名">
|
||||
<input type="password" class="input_text" placeholder="密码">
|
||||
<input type="submit" id="login_btn" value="登录">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 伪类选择器
|
||||
|
||||
当触发某种行为的时候,应用的css样式
|
||||
|
||||
### focus
|
||||
|
||||
当文本框获取光标的时候,会应用的样式
|
||||
|
||||
```css
|
||||
.input_text:focus {
|
||||
width: 220px;
|
||||
border-radius: 30px;
|
||||
border-color: blue;
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
现在动画比较生硬,可以通过设置延迟来改善
|
||||
|
||||
```css
|
||||
.input_text {
|
||||
/* 省略之前的样式 */
|
||||
transition-duration: 0.5s;
|
||||
/* 增加0.5s的改变延迟 */
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### hover
|
||||
|
||||
当鼠标停在上面的时候
|
||||
|
||||
```css
|
||||
#login_btn {
|
||||
/* 省略之前的样式 */
|
||||
transition-duration: 0.5s;
|
||||
/* 增加0.5s的改变延迟 */
|
||||
}
|
||||
|
||||
#login_btn:hover {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
```
|
||||
|
||||
效果如下
|
||||
|
||||

|
||||
|
||||
## 盒子模型
|
||||
|
||||
在html中,每一个元素都有盒子模型
|
||||
|
||||
- 盒子中间是内容
|
||||
- padding:内边距,内容与边框的距离,调整元素内部的布局
|
||||
- border:边框
|
||||
- margin:外边距,边框外面的距离,主要调整元素之间的布局
|
||||
|
||||

|
||||
BIN
project13/01.CSS基础/a6ube-1eqlf.gif
Normal file
|
After Width: | Height: | Size: 4.0 MiB |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"code": "10001",
|
||||
"timeUse": "0.0055",
|
||||
"timeNow": "1734483768.3747",
|
||||
"data": "您尚未登录!请先登录"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"code": "10001",
|
||||
"timeUse": "0.0052",
|
||||
"timeNow": "1734483758.8486",
|
||||
"data": "您尚未登录!请先登录"
|
||||
}
|
||||
BIN
project13/01.CSS基础/image-20241218090404685.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
project13/01.CSS基础/image-20241218090748355.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
project13/01.CSS基础/image-20241218090957562.png
Normal file
|
After Width: | Height: | Size: 571 KiB |
BIN
project13/01.CSS基础/image-20241218091345762.png
Normal file
|
After Width: | Height: | Size: 567 KiB |
BIN
project13/01.CSS基础/image-20241218091758409.png
Normal file
|
After Width: | Height: | Size: 577 KiB |
BIN
project13/01.CSS基础/image-20241218094431541.png
Normal file
|
After Width: | Height: | Size: 720 KiB |
BIN
project13/01.CSS基础/image-20241218094723271.png
Normal file
|
After Width: | Height: | Size: 720 KiB |
BIN
project13/01.CSS基础/ty94l-lpe04.gif
Normal file
|
After Width: | Height: | Size: 6.1 MiB |
BIN
project13/01.CSS基础/wcy72-pdxkm.gif
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
298
project13/02.[任务书]登录注册页面.md
Normal file
@@ -0,0 +1,298 @@
|
||||
# 登录注册页面
|
||||
|
||||
## 需求
|
||||
|
||||
- 开发一个可以点击登录和注册的网页
|
||||
|
||||
## 参考代码
|
||||
|
||||
- login.html
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>欢迎使用</title>
|
||||
<style>
|
||||
body {
|
||||
/* 修改背景 */
|
||||
background: url(https://www.loliapi.com/acg/);
|
||||
/* 背景图 */
|
||||
background-position: center 0;
|
||||
/* 背景水平居中,后面的0表示上下不动 */
|
||||
background-repeat: no-repeat;
|
||||
/* 背景图不要重复 */
|
||||
background-size: cover;
|
||||
/* 背景图大小自动铺满屏幕 */
|
||||
}
|
||||
|
||||
#login_btn {
|
||||
color: white;
|
||||
background: linear-gradient(90deg, red, green, blue, white, orange, yellow);
|
||||
/* 生成渐变色 */
|
||||
background-size: 400%;
|
||||
/* 背景放大 */
|
||||
border: none;
|
||||
/* 边框2px宽,实线,橙色 */
|
||||
border-radius: 10px;
|
||||
/* 边角圆度10px */
|
||||
padding: 10px 20px;
|
||||
/* 内边距,可以看到背景被撑大 */
|
||||
text-shadow: 1px 1px 2px black;
|
||||
/* 文字的阴影效果,上下1px 左右1px 模糊程度2px 颜色gold */
|
||||
transition: 0.5s;
|
||||
animation: move infinite linear 8s;
|
||||
}
|
||||
|
||||
#login_btn:hover {
|
||||
animation: zhuan infinite linear 2s;
|
||||
box-shadow: 0px 0px 20px white;
|
||||
cursor: pointer;
|
||||
padding: 25px 40px;
|
||||
font-size: 28px;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
background-position: 0px;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -400%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zhuan {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
background-position: -400%;
|
||||
}
|
||||
}
|
||||
|
||||
.input_text {
|
||||
background: none;
|
||||
/* 去除背景 */
|
||||
border: 2px solid orange;
|
||||
padding: 15px 20px;
|
||||
margin: 10px auto;
|
||||
/* 外边距,上下10px,左右居中自动调整 */
|
||||
width: 180px;
|
||||
/* 宽度 */
|
||||
text-align: center;
|
||||
/* 文字居中 */
|
||||
outline: none;
|
||||
/* 外部的线,只有文本框被选择的时候出现 */
|
||||
color: white;
|
||||
font-size: 22px;
|
||||
/* 字体大小 */
|
||||
display: block;
|
||||
/* block显示模式,是一个占据一整行,inline是不占据一整行 */
|
||||
border-radius: 10px;
|
||||
transition: 0.5s;
|
||||
/* 当属性值发生变化的时候,需要经历的时间 */
|
||||
}
|
||||
|
||||
.input_text:focus {
|
||||
width: 220px;
|
||||
border-radius: 30px;
|
||||
border-color: blue;
|
||||
}
|
||||
|
||||
.input_text::placeholder {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.box {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
/* 绝对定位,基于浏览器窗口定位 */
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
/* 基于元素本身的大小,往左上移动50% */
|
||||
border: none;
|
||||
color: aliceblue;
|
||||
text-align: center;
|
||||
padding: 10px 50px;
|
||||
border-radius: 20px;
|
||||
width: 280px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<form action="" method="post">
|
||||
<h1>欢迎登录</h1>
|
||||
<input class="input_text" name="username" type="text" placeholder="用户名">
|
||||
<!-- placeholder属性用于文本框的提示 -->
|
||||
<input class="input_text" name="password" type="password" placeholder="密码">
|
||||
<input id="login_btn" name="login" type="submit" value="登录">
|
||||
<input id="login_btn" type="button" onclick="window.location.href='register.html'" value="注册">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
- register.html
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>欢迎使用</title>
|
||||
<style>
|
||||
body {
|
||||
/* 修改背景 */
|
||||
background: url(https://www.loliapi.com/acg/);
|
||||
/* 背景图 */
|
||||
background-position: center 0;
|
||||
/* 背景水平居中,后面的0表示上下不动 */
|
||||
background-repeat: no-repeat;
|
||||
/* 背景图不要重复 */
|
||||
background-size: cover;
|
||||
/* 背景图大小自动铺满屏幕 */
|
||||
}
|
||||
|
||||
#login_btn {
|
||||
color: white;
|
||||
background: linear-gradient(90deg, red, green, blue, white, orange, yellow);
|
||||
/* 生成渐变色 */
|
||||
background-size: 400%;
|
||||
/* 背景放大 */
|
||||
border: none;
|
||||
/* 边框2px宽,实线,橙色 */
|
||||
border-radius: 10px;
|
||||
/* 边角圆度10px */
|
||||
padding: 10px 20px;
|
||||
/* 内边距,可以看到背景被撑大 */
|
||||
text-shadow: 1px 1px 2px black;
|
||||
/* 文字的阴影效果,上下1px 左右1px 模糊程度2px 颜色gold */
|
||||
transition: 0.5s;
|
||||
animation: move infinite linear 8s;
|
||||
}
|
||||
|
||||
#login_btn:hover {
|
||||
animation: zhuan infinite linear 2s;
|
||||
box-shadow: 0px 0px 20px white;
|
||||
cursor: pointer;
|
||||
padding: 25px 40px;
|
||||
font-size: 28px;
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
0% {
|
||||
background-position: 0px;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -400%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zhuan {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
background-position: -400%;
|
||||
}
|
||||
}
|
||||
|
||||
.input_text {
|
||||
background: none;
|
||||
/* 去除背景 */
|
||||
border: 2px solid orange;
|
||||
padding: 15px 20px;
|
||||
margin: 10px auto;
|
||||
/* 外边距,上下10px,左右居中自动调整 */
|
||||
width: 180px;
|
||||
/* 宽度 */
|
||||
text-align: center;
|
||||
/* 文字居中 */
|
||||
outline: none;
|
||||
/* 外部的线,只有文本框被选择的时候出现 */
|
||||
color: white;
|
||||
font-size: 22px;
|
||||
/* 字体大小 */
|
||||
display: block;
|
||||
/* block显示模式,是一个占据一整行,inline是不占据一整行 */
|
||||
border-radius: 10px;
|
||||
transition: 0.5s;
|
||||
/* 当属性值发生变化的时候,需要经历的时间 */
|
||||
}
|
||||
|
||||
.input_text:focus {
|
||||
width: 220px;
|
||||
border-radius: 30px;
|
||||
border-color: blue;
|
||||
}
|
||||
|
||||
.input_text::placeholder {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.box {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
/* 绝对定位,基于浏览器窗口定位 */
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
/* 基于元素本身的大小,往左上移动50% */
|
||||
border: none;
|
||||
color: aliceblue;
|
||||
text-align: center;
|
||||
padding: 10px 50px;
|
||||
border-radius: 20px;
|
||||
width: 280px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="box">
|
||||
<form action="" method="post">
|
||||
<h1>欢迎注册</h1>
|
||||
<input class="input_text" name="username" type="text" placeholder="用户名">
|
||||
<!-- placeholder属性用于文本框的提示 -->
|
||||
<input class="input_text" name="password" type="text" placeholder="密码">
|
||||
<input class="input_text" name="confirmPassword" type="text" placeholder="确认密码">
|
||||
<input id="login_btn" name="register" type="submit" value="注册">
|
||||
<input id="login_btn" type="button" onclick="window.location.href='login.html'" value="登录">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
效果展示
|
||||
|
||||
<video src="https://static.eagleslab.com/python-c73d2e01-83a8-17ef-e0b9-59b3ab5fc599/project13/效果展示.mp4" width="100%" controls>
|
||||
您的浏览器不支持 Video 标签。
|
||||
</video>
|
||||
|
||||
><span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业13.1提交的内容</span>
|
||||
>
|
||||
>- 理解程序的运行逻辑
|
||||
>- 程序运行成功的截图,单独发送给组长
|
||||
399
project14/01.SQLAlchemy.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# 介绍
|
||||
|
||||
`SQLAlchemy`是一个数据库的`ORM`框架,让我们操作数据库的时候不要再用`SQL`语句了,跟直接操作模型一样。安装命令为:`pip install SQLAlchemy`。
|
||||
|
||||
# 连接数据库
|
||||
|
||||
前面的学习我们已经掌握了如何在本地部署mysql服务了,现在将mysql启动之后,创建测试的数据库
|
||||
|
||||
- 点击`start.bat` 启动mysql数据库
|
||||
|
||||

|
||||
|
||||
- 点击`connect.bat` 连接到数据库中
|
||||
|
||||

|
||||
|
||||
- 输入如下命令创建数据库
|
||||
|
||||
```sql
|
||||
create database login;
|
||||
show databases;
|
||||
```
|
||||
|
||||

|
||||
|
||||
- 执行下面的代码
|
||||
|
||||
```python
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import text
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
HOSTNAME = 'localhost'
|
||||
# 数据库地址
|
||||
PORT = 3306
|
||||
# 数据库端口号
|
||||
USERNAME = "root"
|
||||
# 数据库用户名
|
||||
PASSWORD = "usbw"
|
||||
# 数据库密码
|
||||
DATABASE = "login"
|
||||
# 数据库名
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}/{DATABASE}?charset=utf8'
|
||||
# 配置flask连接数据库的配置
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
# 连接数据库,并且拿到连接的接口
|
||||
|
||||
with app.app_context():
|
||||
rs = db.session.execute(text('select 1'))
|
||||
# 执行一个测试的sql语句
|
||||
print(rs.fetchone())
|
||||
# 输出测试结果
|
||||
```
|
||||
|
||||
# 创建表
|
||||
|
||||
- 在`flask_sqlalchemy` 中,一个表就对应一个类,所以想要创建对应的表,就要先把类创建好
|
||||
- 在类中,我们可以定义这个表中应该有哪些数据
|
||||
|
||||
```python
|
||||
class User(db.Model):
|
||||
# 这个类是对应了user这个表
|
||||
__tablename__ = 'user'
|
||||
# 设置表的选项,包括字符集为utf8
|
||||
__table_args__ = {
|
||||
'mysql_charset': 'utf8',
|
||||
'mysql_collate': 'utf8_general_ci'
|
||||
}
|
||||
# 设置表名
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
# 第一列数据,列名为id,后面对应的参数是(整数类型,主键,自动增长)
|
||||
username = db.Column(db.String(100), unique=True, nullable=False)
|
||||
# username列,长度为100的字符串,唯一,不能为空
|
||||
password = db.Column(db.String(100), nullable=False)
|
||||
# password列,长度为100的字符串,不能为空
|
||||
|
||||
|
||||
with app.app_context():
|
||||
# 如果想要在主程序中调用数据库,就要启动上下文管理
|
||||
db.create_all()
|
||||
# 创建对应的表,不用担心反复创建,sqlalchemy会自动处理好幂等性
|
||||
```
|
||||
|
||||
- 代码运行后,可以查看数据库中已经存在对应的表,并且按照要求创建好
|
||||
|
||||
```sql
|
||||
use login
|
||||
show tables;
|
||||
explain user;
|
||||
```
|
||||
|
||||

|
||||
|
||||
# 插入数据
|
||||
|
||||
- 创建一个网页,当我们访问这个页面的时候就插入多个用户
|
||||
|
||||
```python
|
||||
@app.route("/user/add")
|
||||
def user_add():
|
||||
user1 = User(username="user01", password="123456")
|
||||
# 实例化一个用户对象
|
||||
user2 = User(username="user02", password="123456")
|
||||
user3 = User(username="user03", password="123456")
|
||||
db.session.add(user1)
|
||||
# 实例化一个用户对象,将这个对象加到db接口中
|
||||
db.session.add(user2)
|
||||
db.session.add(user3)
|
||||
db.session.commit()
|
||||
# 提交更改的内容
|
||||
return "用户创建成功!"
|
||||
|
||||
|
||||
app.run(debug=True, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
- 访问此页面
|
||||
|
||||

|
||||
|
||||
- 从命令行里面查看,确认数据都已经创建
|
||||
|
||||
```sql
|
||||
mysql> select * from user;
|
||||
+----+----------+----------+
|
||||
| id | username | password |
|
||||
+----+----------+----------+
|
||||
| 1 | user01 | 123456 |
|
||||
| 2 | user02 | 123456 |
|
||||
| 3 | user03 | 123456 |
|
||||
+----+----------+----------+
|
||||
3 rows in set (0.00 sec)
|
||||
```
|
||||
|
||||
# 查询数据
|
||||
|
||||
- 单独写一个页面用于用户数据的查询
|
||||
|
||||
```python
|
||||
@app.route("/user/fetch")
|
||||
def user_fetch():
|
||||
user = User.query.filter(and_(User.username == "user01", User.password == "123456")).all()
|
||||
# 获取用户对象,查询用户名和密码是否正确
|
||||
if len(user) == 0:
|
||||
# 如果查询到的结果是0,说明没有用户名和密码是对的
|
||||
return "用户名或密码不正确"
|
||||
else:
|
||||
return f"欢迎用户{user[0].username}登录成功!"
|
||||
```
|
||||
|
||||
- 访问测试
|
||||
|
||||

|
||||
|
||||
# 登录功能实现
|
||||
|
||||
## 登录页面
|
||||
|
||||
- 创建模板的文件夹`templates`,并且将前面的登录注册页面放进去
|
||||
|
||||

|
||||
|
||||
- 编写python代码,将登录页渲染到模版中
|
||||
|
||||
```python
|
||||
from flask import Flask, render_template
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return render_template("login.html")
|
||||
|
||||
|
||||
app.run(debug=True, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
- 访问效果如下
|
||||
|
||||

|
||||
|
||||
## 后端业务逻辑
|
||||
|
||||
- 修改前端源码,将注册按钮跳转地址改为`/register`
|
||||
|
||||

|
||||
|
||||
- 修改python代码
|
||||
- 增加允许的提交方法是`POST`
|
||||
- 接受用户名和密码,并且拉入数据库进行比对
|
||||
- 返回登录结果
|
||||
|
||||
```python
|
||||
from flask import Flask, render_template, request
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import text, and_
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
HOSTNAME = 'localhost'
|
||||
# 数据库地址
|
||||
PORT = 3306
|
||||
# 数据库端口号
|
||||
USERNAME = "root"
|
||||
# 数据库用户名
|
||||
PASSWORD = "123456"
|
||||
# 数据库密码
|
||||
DATABASE = "login"
|
||||
# 数据库名
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}/{DATABASE}?charset=utf8'
|
||||
# 配置flask连接数据库的配置
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
class User(db.Model):
|
||||
# 这个类是对应了user这个表
|
||||
__tablename__ = 'user'
|
||||
# 设置表的选项,包括字符集为utf8
|
||||
__table_args__ = {
|
||||
'mysql_charset': 'utf8',
|
||||
'mysql_collate': 'utf8_general_ci'
|
||||
}
|
||||
# 设置表名
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
# 第一列数据,列名为id,后面对应的参数是(整数类型,主键,自动增长)
|
||||
username = db.Column(db.String(100), unique=True, nullable=False)
|
||||
# username列,长度为100的字符串,唯一,不能为空
|
||||
password = db.Column(db.String(100), nullable=False)
|
||||
# password列,长度为100的字符串,不能为空
|
||||
|
||||
|
||||
with app.app_context():
|
||||
# 如果想要在主程序中调用数据库,就要启动上下文管理
|
||||
db.create_all()
|
||||
# 创建对应的表
|
||||
@app.route("/", methods=['GET', 'POST'])
|
||||
def index():
|
||||
if request.method == 'POST':
|
||||
# 如果是post请求,说明是提交过来的请求
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
user = User.query.filter(and_(User.username == username, User.password == password)).all()
|
||||
# 获取用户对象,查询用户名和密码是否正确
|
||||
if len(user) == 0:
|
||||
# 如果查询到的结果是0,说明没有用户名和密码是对的
|
||||
return "用户名或密码不正确"
|
||||
else:
|
||||
return f"欢迎用户{user[0].username}登录成功!"
|
||||
return render_template("login.html")
|
||||
|
||||
|
||||
app.run(debug=True, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
- 在页面中测试登录成功或失败
|
||||
|
||||
# 注册功能实现
|
||||
|
||||
## 注册页面
|
||||
|
||||
- 编写python代码,将注册页渲染到模版中
|
||||
|
||||
```python
|
||||
@app.route("/register", methods=['GET', 'POST'])
|
||||
def register():
|
||||
return render_template("register.html")
|
||||
```
|
||||
|
||||
- 访问效果如下
|
||||
|
||||

|
||||
|
||||
## 后端业务逻辑
|
||||
|
||||
- 修改`register.html`中的跳转代码。点击登录,可以正确的跳转到登录页面
|
||||
|
||||

|
||||
|
||||
- 修改python代码
|
||||
- 获取前端输入的用户名和两次输入的密码
|
||||
- 如果用户名已存在就直接显示用户名已存在
|
||||
- 用户名不存在,但是两次密码不一样,就直接显示两次密码不一致
|
||||
- 如果用户名不存在,且密码符合要求,就将用户名和密码加入数据库中,直接显示注册成功
|
||||
|
||||
```python
|
||||
from flask import Flask, render_template, request
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import text, and_
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
HOSTNAME = 'localhost'
|
||||
# 数据库地址
|
||||
PORT = 3306
|
||||
# 数据库端口号
|
||||
USERNAME = "root"
|
||||
# 数据库用户名
|
||||
PASSWORD = "123456"
|
||||
# 数据库密码
|
||||
DATABASE = "login"
|
||||
# 数据库名
|
||||
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}/{DATABASE}?charset=utf8'
|
||||
# 配置flask连接数据库的配置
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
|
||||
class User(db.Model):
|
||||
# 这个类是对应了user这个表
|
||||
__tablename__ = 'user'
|
||||
|
||||
# 设置表的选项,包括字符集为utf8
|
||||
__table_args__ = {
|
||||
'mysql_charset': 'utf8',
|
||||
'mysql_collate': 'utf8_general_ci'
|
||||
}
|
||||
|
||||
# 设置表名
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
# 第一列数据,列名为id,后面对应的参数是(整数类型,主键,自动增长)
|
||||
username = db.Column(db.String(100), unique=True, nullable=False)
|
||||
# username列,长度为100的字符串,唯一,不能为空
|
||||
password = db.Column(db.String(100), nullable=False)
|
||||
# password列,长度为100的字符串,不能为空
|
||||
|
||||
|
||||
with app.app_context():
|
||||
# 如果想要在主程序中调用数据库,就要启动上下文管理
|
||||
db.create_all()
|
||||
# 创建对应的表
|
||||
|
||||
|
||||
@app.route("/user/add")
|
||||
def user_add():
|
||||
user1 = User(username="user01", password="123456")
|
||||
# 实例化一个用户对象
|
||||
user2 = User(username="user02", password="123456")
|
||||
user3 = User(username="user03", password="123456")
|
||||
db.session.add(user1)
|
||||
# 实例化一个用户对象,将这个对象加到db接口中
|
||||
db.session.add(user2)
|
||||
db.session.add(user3)
|
||||
db.session.commit()
|
||||
# 提交更改的内容
|
||||
return "用户创建成功!"
|
||||
|
||||
|
||||
@app.route("/", methods=['GET', 'POST'])
|
||||
def index():
|
||||
if request.method == 'POST':
|
||||
# 如果是post请求,说明是提交过来的请求
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
user = User.query.filter(and_(User.username == username, User.password == password)).all()
|
||||
# 获取用户对象,查询用户名和密码是否正确
|
||||
if len(user) == 0:
|
||||
# 如果查询到的结果是0,说明没有用户名和密码是对的
|
||||
return "用户名或密码不正确"
|
||||
else:
|
||||
return f"欢迎用户{user[0].username}登录成功!"
|
||||
return render_template("login.html")
|
||||
|
||||
|
||||
@app.route("/register", methods=['GET', 'POST'])
|
||||
def register():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
confirm_password = request.form.get('confirmPassword')
|
||||
user = User.query.filter_by(username=username).all()
|
||||
# 判断用户名是否存在
|
||||
if len(user) > 0:
|
||||
print(user)
|
||||
return "用户名已存在"
|
||||
if password != confirm_password:
|
||||
# 判断两次密码是否一致
|
||||
return "两次密码不一致"
|
||||
temp_user = User(username=username, password=password)
|
||||
db.session.add(temp_user)
|
||||
db.session.commit()
|
||||
# 将用户名和密码加入数据库
|
||||
return "注册成功"
|
||||
return render_template("register.html")
|
||||
|
||||
|
||||
app.run(debug=True, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
- 最后测试一下是否能够正常的注册与登录
|
||||
|
||||

|
||||
|
||||
BIN
project14/01.SQLAlchemy/image-20241219144614007.png
Normal file
|
After Width: | Height: | Size: 545 KiB |
BIN
project14/01.SQLAlchemy/image-20241219144653494.png
Normal file
|
After Width: | Height: | Size: 686 KiB |
BIN
project14/01.SQLAlchemy/image-20241219144732276.png
Normal file
|
After Width: | Height: | Size: 452 KiB |
BIN
project14/01.SQLAlchemy/image-20241219145706987.png
Normal file
|
After Width: | Height: | Size: 562 KiB |
BIN
project14/01.SQLAlchemy/image-20241219150537129.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
project14/01.SQLAlchemy/image-20241219150755302.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
project14/01.SQLAlchemy/image-20241219152029971.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
project14/01.SQLAlchemy/image-20241219152938127.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
project14/01.SQLAlchemy/image-20241219153544582.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
project14/01.SQLAlchemy/image-20241219153752702.png
Normal file
|
After Width: | Height: | Size: 154 KiB |
BIN
project14/01.SQLAlchemy/image-20241219154701791.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
project14/01.SQLAlchemy/image-20241219154828636.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
project14/01.SQLAlchemy/image-20241219164014985.png
Normal file
|
After Width: | Height: | Size: 233 KiB |
15
project14/02.[任务书]登录注册功能.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# 登录注册功能
|
||||
|
||||
## 需求
|
||||
|
||||
- 学习`SQLAlchemy` 相关的使用方式
|
||||
- 完成课件中的案例,登录注册功能
|
||||
|
||||
## 参考代码
|
||||
|
||||
- 就在课件中,如果不会使用,请查看视频
|
||||
|
||||
> <span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业14.1提交的内容</span>
|
||||
>
|
||||
> - 理解程序的运行逻辑
|
||||
> - 程序运行成功的截图,单独发送给组长
|
||||
328
project15/01.jinja2模板.md
Normal file
@@ -0,0 +1,328 @@
|
||||
# 模版简介
|
||||
|
||||
模板是一个`web`开发必备的模块。因为我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要渲染一个有富文本标签的页面。这时候我们就需要使用模板了。在`Flask`中,配套的模板是`Jinja2`,`Jinja2`的作者也是`Flask`的作者。这个模板非常的强大,并且执行效率高。以下对`Jinja2`做一个简单介绍!
|
||||
|
||||
## 渲染`Jinja`模板
|
||||
|
||||
要渲染一个模板,通过`render_template`方法即可,以下将用一个简单的例子进行讲解:
|
||||
|
||||
创建about.html
|
||||
|
||||
```jinja2
|
||||
<h1>welcome back!</h1>
|
||||
```
|
||||
|
||||
执行下面代码
|
||||
|
||||
```python
|
||||
from flask import Flask,render_template
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/about/')
|
||||
def about():
|
||||
return render_template('about.html')
|
||||
# 渲染 about.html 注意:必须要在 templates 文件夹下
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True,host='0.0.0.0',port=5000)
|
||||
```
|
||||
|
||||
当访问`/about/`的时候,`about()`函数会在当前目录下的`templates`文件夹下寻找`about.html`模板文件。如果想更改模板文件地址,应该在创建`app`的时候,给`Flask`传递一个关键字参数`template_folder`,指定具体的路径,再看以下例子:
|
||||
|
||||
```python
|
||||
from flask import Flask,render_template
|
||||
app = Flask(__name__,template_folder=r'C:\templates')
|
||||
|
||||
@app.route('/about/')
|
||||
def about():
|
||||
return render_template('about.html')
|
||||
```
|
||||
|
||||
以上例子将会在C盘的`templates`文件夹中寻找模板文件。还有最后一点是,如果模板文件中有参数需要传递,应该怎么传呢,我们再来看一个例子:
|
||||
|
||||
about.html 修改为如下
|
||||
|
||||
```html
|
||||
<h1>welcome {{ user }} </h1>
|
||||
```
|
||||
|
||||
在渲染模版的时候传递一下参数
|
||||
|
||||
```python
|
||||
@app.route('/about/')
|
||||
def about():
|
||||
return render_template('about.html', user='user01')
|
||||
```
|
||||
|
||||
如果有多个参数要传递的话可以放在字典中
|
||||
|
||||
```python
|
||||
@app.route('/about/')
|
||||
def about():
|
||||
return render_template('about.html', **{'user':'alice','name':'bob'})
|
||||
# about.html 中需要有 user 和 name
|
||||
```
|
||||
|
||||
以上例子介绍了两种传递参数的方式,因为`render_template`需要传递的是一个关键字参数,所以第一种方式是顺其自然的。但是当你的模板中要传递的参数过多的时候,把所有参数放在一个函数中显然不是一个好的选择,因此我们使用字典进行包装,并且加两个`*`号,来转换成关键字参数。
|
||||
|
||||
# Jinja2模版概述
|
||||
|
||||
## 概要
|
||||
|
||||
先看一个简单例子:
|
||||
|
||||
```html
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>My Webpage</title>
|
||||
</head>
|
||||
<body>
|
||||
<ul id="navigation">
|
||||
{% for item in navigation %}
|
||||
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{{ a_variable }}
|
||||
{{ user.name }}
|
||||
{{ user['name'] }}
|
||||
|
||||
{# a comment #}
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
以上示例有需要进行解释:
|
||||
|
||||
- 第12~14行的`{{ ... }}`:用来装载一个变量,模板渲染的时候,会把这个变量代表的值替换掉。并且可以间接访问一个变量的属性或者一个字典的`key`。关于点`.`号访问和`[]`中括号访问,没有任何区别,都可以访问属性和字典的值。
|
||||
- 第7~9行的`{% ... %}`:用来装载一个控制语句,以上装载的是`for`循环,以后只要是要用到控制语句的,就用`{% ... %}`。
|
||||
- 第16行的`{# ... #}`:用来装载一个注释,模板渲染的时候会忽视这中间的值。
|
||||
|
||||
对应的 Python 代码如下
|
||||
|
||||
```python
|
||||
@app.route('/demo1/')
|
||||
def demo1():
|
||||
navigation = [
|
||||
{'href':'http://www.baidu.com','caption':'百度'},
|
||||
{'href':'http://www.qq.com','caption':'腾讯'}
|
||||
]
|
||||
a = 'hello world'
|
||||
user = {'name':'alice'}
|
||||
return render_template('demo1.html', navigation=navigation, a_variable=a, user=user)
|
||||
```
|
||||
|
||||
# Jinja2 模版过滤器
|
||||
|
||||
过滤器是通过管道符号(`|`)进行使用的,例如:`{{ name|length }}`,将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。`Jinja2`中内置了许多过滤器,在[这里](https://jinja.palletsprojects.com/en/3.0.x/templates/#list-of-builtin-filters)可以看到所有的过滤器,现对一些常用的过滤器进行讲解:
|
||||
|
||||
1. `abs(value)`:返回一个数值的绝对值。 例如:`-1|abs`。
|
||||
|
||||
2. `default(value,default_value,boolean=false)`:如果当前变量没有值,则会使用参数中的值来代替。`name|default('alice')`——如果name不存在,则会使用`alice`来替代。`boolean=False`默认是在只有这个变量为`undefined`的时候才会使用`default`中的值,如果想使用`python`的形式判断是否为`false`,则可以传递`boolean=true`。也可以使用`or`来替换。
|
||||
|
||||
3. `escape(value)或e`:转义字符,会将`<`、`>`等符号转义成HTML中的符号。例如:`content|escape`或`content|e`。
|
||||
|
||||
4. `first(value)`:返回一个序列的第一个元素。`names|first`。
|
||||
|
||||
5. `format(value,*arags,**kwargs)`:格式化字符串。例如以下代码:
|
||||
|
||||
```html
|
||||
{{ "%s - %s"|format("hello","alice") }}
|
||||
```
|
||||
|
||||
将输出:Hello - alice
|
||||
|
||||
6. `last(value)`:返回一个序列的最后一个元素。示例:`names|last`。
|
||||
|
||||
7. `length(value)`:返回一个序列或者字典的长度。示例:`names|length`。
|
||||
|
||||
8. `join(value,d=u'')`:将一个序列用`d`这个参数的值拼接成字符串。
|
||||
|
||||
9. `safe(value)`:如果开启了全局转义,那么`safe`过滤器会将变量关掉转义。示例:`content_html|safe`。
|
||||
|
||||
10. `int(value)`:将值转换为`int`类型。
|
||||
|
||||
11. `float(value)`:将值转换为`float`类型。
|
||||
|
||||
12. `lower(value)`:将字符串转换为小写。
|
||||
|
||||
13. `upper(value)`:将字符串转换为大写。
|
||||
|
||||
14. `replace(value,old,new)`: 替换将`old`替换为`new`的字符串。
|
||||
|
||||
15. `truncate(value,length=255,killwords=False)`:截取`length`长度的字符串。
|
||||
|
||||
16. `striptags(value)`:删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
|
||||
|
||||
17. `trim`:截取字符串前面和后面的空白字符。
|
||||
|
||||
18. `string(value)`:将变量转换成字符串。
|
||||
|
||||
19. `wordcount(s)`:计算一个长字符串中单词的个数。
|
||||
|
||||
# 控制语句
|
||||
|
||||
所有的控制语句都是放在`{% ... %}`中,并且有一个语句`{% endxxx %}`来进行结束,`Jinja`中常用的控制语句有`if/for..in..`,现对他们进行讲解:
|
||||
|
||||
1. `if`:if语句和`python`中的类似,可以使用`>,<,<=,>=,==,!=`来进行判断,也可以通过`and,or,not,()`来进行逻辑合并操作,以下看例子:
|
||||
|
||||
```jinja2
|
||||
{% if num < 60 %}
|
||||
你猜的数字小了
|
||||
{% elif num > 60 %}
|
||||
你猜的数字大了
|
||||
{% else %}
|
||||
你猜对了
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
2. `for...in...`:`for`循环可以遍历任何一个序列包括列表、字典、元组。并且可以进行反向遍历,以下将用几个例子进行解释:
|
||||
|
||||
- 普通的遍历:
|
||||
|
||||
```jinja2
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li>{{ user.username|e }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
- 遍历字典:
|
||||
|
||||
```jinja2
|
||||
<dl>
|
||||
{% for key, value in my_dict.items() %}
|
||||
<dt>{{ key|e }}</dt>
|
||||
<dd>{{ value|e }}</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
```
|
||||
|
||||
- 如果序列中没有值的时候,进入`else`:
|
||||
|
||||
```jinja2
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li>{{ user.username|e }}</li>
|
||||
{% else %}
|
||||
<li><em>no users found</em></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
并且`Jinja2`中的`for`循环还包含以下变量,可以用来获取当前的遍历状态:
|
||||
|
||||
| 变量 | 描述 |
|
||||
| :---------- | :---------------------------------- |
|
||||
| loop.index | 当前迭代的索引(从1开始) |
|
||||
| loop.index0 | 当前迭代的索引(从0开始) |
|
||||
| loop.first | 是否是第一次迭代,返回True或False |
|
||||
| loop.last | 是否是最后一次迭代,返回True或False |
|
||||
| loop.length | 序列的长度 |
|
||||
|
||||
另外,**不可以**使用`continue`和`break`表达式来控制循环的执行。
|
||||
|
||||
# 测试器
|
||||
|
||||
测试器主要用来判断一个值是否满足某种类型,并且这种类型一般通过普通的`if`判断是有很大的挑战的。语法是:`if...is...`,先来简单的看个例子:
|
||||
|
||||
```jinja2
|
||||
{% if variable is upper %}
|
||||
value of variable: {{ variable }}
|
||||
{% else %}
|
||||
variable is not upper
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
以上判断`variable`这个变量是否全大写,`Jinja`中内置了许多的测试器,看以下列表:
|
||||
|
||||
| 测试器 | 说明 |
|
||||
| :----------------- | :----------------- |
|
||||
| `callable(object)` | 是否可调用 |
|
||||
| `defined(object)` | 是否已经被定义了。 |
|
||||
| `escaped(object)` | 是否已经被转义了。 |
|
||||
| `upper(object)` | 是否全是大写。 |
|
||||
| `lower(object)` | 是否全是小写。 |
|
||||
| `string(object)` | 是否是一个字符串。 |
|
||||
| `sequence(object)` | 是否是一个序列。 |
|
||||
| `number(object)` | 是否是一个数字。 |
|
||||
| `odd(object)` | 是否是奇数。 |
|
||||
| `even(object)` | 是否是偶数。 |
|
||||
|
||||
## 赋值(set)语句
|
||||
|
||||
有时候我们想在在模板中添加变量,这时候赋值语句(set)就派上用场了,先看以下例子:
|
||||
|
||||
```jinja2
|
||||
{% set name='eagle' %}
|
||||
```
|
||||
|
||||
那么以后就可以使用`name`来代替`eagle`这个值了,同时,也可以给他赋值为列表和元组:
|
||||
|
||||
```jinja2
|
||||
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
|
||||
```
|
||||
|
||||
赋值语句创建的变量在其之后都是有效的,如果不想让一个变量污染全局环境,可以使用`with`语句来创建一个内部的作用域,将`set`语句放在其中,这样创建的变量只在`with`代码块中才有效,看以下示例:
|
||||
|
||||
```jinja2
|
||||
{% with %}
|
||||
{% set foo = 42 %}
|
||||
{{ foo }} foo is 42 here
|
||||
{% endwith %}
|
||||
```
|
||||
|
||||
也可以在`with`的后面直接添加变量,比如以上的写法可以修改成这样:
|
||||
|
||||
```jinja2
|
||||
{% with foo = 42 %}
|
||||
{{ foo }}
|
||||
{% endwith %}
|
||||
```
|
||||
|
||||
这两种方式都是等价的,一旦超出`with`代码块,就不能再使用`foo`这个变量了。
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
{% set name="alice" %}
|
||||
<h1>欢迎{{ name }}</h1>
|
||||
{% set link=[('http://www.baidu.com','百度'),('http://www.qq.com','腾讯')] %}
|
||||
<ul>
|
||||
{% for i in link %}
|
||||
<li><a href="{{ i[0] }}">{{ i[1] }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% set foo=24 %}
|
||||
{% with foo=88 %}
|
||||
<p>在局部作用域中的值:{{ foo }}</p>
|
||||
{% endwith %}
|
||||
<p>在全局作用域中的值:{{ foo }}</p>
|
||||
{# with中的修改不会影响全局的内容 #}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# 静态文件的配置
|
||||
|
||||
`Web`应用中会出现大量的静态文件来使得网页更加生动美观。类似于`CSS`样式文件、`JavaScript`脚本文件、图片文件、字体文件等静态资源。在`Jinja`中加载静态文件非常简单,只需要通过`url_for`全局函数就可以实现,看以下代码:
|
||||
|
||||
```html
|
||||
<link href="{{ url_for('static',filename='about.css') }}">
|
||||
```
|
||||
|
||||
`url_for`函数默认会在项目根目录下的`static`文件夹中寻找`about.css`文件,如果找到了,会生成一个相对于项目根目录下的`/static/about.css`路径。当然我们也可以把静态文件不放在`static`文件夹中,此时就需要具体指定了,看以下代码:
|
||||
|
||||
```python
|
||||
app = Flask(__name__,static_folder='C:\static')
|
||||
```
|
||||
|
||||
那么访问静态文件的时候,将会到`/static`这个文件夹下寻找。
|
||||
BIN
project15/01.jinja2模板/image-20240326140211392.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
26
project15/02.[任务书]用户管理系统.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 用户管理系统
|
||||
|
||||
## 需求
|
||||
|
||||
- 结合任务14的登录注册功能,让用户登录成功之后,可以看到所有已经注册的用户
|
||||
- 提供删除和修改密码功能
|
||||
- 用户管理系统前端代码:https://www.123865.com/s/BKNfTd-XiXKA提取码:6666
|
||||
|
||||
## 参考页面
|
||||
|
||||
- 用户列表页面
|
||||
|
||||

|
||||
|
||||
- 修改密码界面
|
||||
|
||||

|
||||
|
||||
## 项目参考代码
|
||||
|
||||
- 代码下载地址:https://www.123865.com/s/BKNfTd-niXKA提取码:6666
|
||||
|
||||
> <span style="color: red; background: yellow; padding: 2px 5px; font-size: 22px;">作业15.1提交的内容</span>
|
||||
>
|
||||
> - 理解程序的运行逻辑
|
||||
> - 程序运行成功的截图,单独发送给组长
|
||||
BIN
project15/02.[任务书]用户管理系统/image-20241228140824615.png
Normal file
|
After Width: | Height: | Size: 134 KiB |