Python / Anaconda / Django

Python是一种高级、通用、解释型、面向对象的编程语言。
Python是一种解释型语言,其代码不是直接编译成机器码,而是由解释器逐行解释执行。常见的Python解释器有 CPython、Jython 等。
其中 CPython 是官方标准实现,是由Python的创始人Guido van Rossum领导开发的官方Python解释器。它是使用C语言编写的,是最广泛使用的Python解释器。

Python 环境

  1. 配置 Python 环境:
    • 官方Python(CPython):通过官方网站下载并安装,使用官方的 pip 包管理器进行包的安装。不具备虚拟环境管理工具,但可使用 venv 或 virtualenv 创建虚拟环境。
      使用:添加解释器 -> Virtualenv -> 基础解释器 -> C:\Users\caife\AppData\Local\Programs\Python\Python312\python.exe
    • Anaconda Python:通过 Anaconda 官方网站下载并安装。使用 conda 包管理器进行包的安装和环境的管理。具备强大的虚拟环境管理工具,可以轻松创建、导出、列出和删除环境。
    • 项目中自带的环境:在开发环境中配置项目中的 Python 解释器(xxproject\env\Scripts\python.exe),使项目中使用的 Python 环境与系统中的 Python 环境独立。
  2. Python环境通常包括了解释器、标准库、开发工具和其他一些组件:
    • 虚拟环境(Virtual Environment): 虚拟环境是一个独立的Python环境,允许您在同一台机器上同时运行多个项目,每个项目都有其独立的依赖项和库。venvvirtualenv 是用于创建虚拟环境的工具。
    • 解释器:如 C:\Python312\python.exe,用于运行代码。
    • 包管理器:如 C:\Python312\Scripts\pip3.exe,用于(为解释器/环境)安装、升级和卸载软件包。pip 是Python的官方包管理器,用于从 PyPI 安装第三方库。
    • 库:如 C:\Python312\lib,其中包含了该环境中安装的所有Python包。
  3. 开发环境:
    • IDE(集成开发环境):提供了代码编辑、调试、版本控制等一体化功能的工具。常见的 Python IDE包括 PyCharm、Visual Studio Code、Jupyter Notebook 等。
    • Jupyter Notebook: 交互式计算环境,支持在浏览器中编写和运行 Python代码,并包含文本、图像和公式等。
  4. PyCharm 配置解释器:
    • 使用 Pycharm 开发项目时, 点击添加解释器 —> 添加本地解释器,选择将要运行该项目的虚拟环境下的 Python 解释器。
      选择使用这个虚拟环境对应的编辑器,就是选择了使用这个环境运行项目,使用这个环境中配好的包,版本和依赖库等等。 可以在“外部库”查看当前环境中的类库。
    • 一般来说, 可以直接选择本地Python解释器(Python3.10)环境中已经配好了大部分的类库,项目中需要的软件包可以手动安装(指定地址 C:\Users\caife\AppData\Local\Programs\Python\Python312\Lib)。
  5. PyCharm终端的Python环境不一定与当前加载的项目使用的解释器器环境一致!!
    • 所以要注意终端使用的是哪个编辑器,是否与当前项目使用的编辑器匹配。否则在终端 pip install 把包装到 Pycharm 终端的环境下,而当前项目运行在另一个虚拟环境中,便无法 import 已从终端安装的包。
    • 看pycharm提示符的地址,其实就等于是cmd中cd到该地址执行命令

Pycharm 终端指令

1
2
3
4
pip install xx    # pip安装包到终端的环境中
pip install xx --target C:\Users\caife\AppData\Local\Programs\Python\Python312\Lib # 指定安装位置
python --version # 查看 Python 版本
pip list # 列出已安装的包

数据结构与函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
my_list = [1, 2, 3, "apple"]  # 列表
my_tuple = (1, 2, 3) # 元组
my_dict = {"name": "John", "age": 25} # 字典
my_set = {1, 2, 3} # 集合

# 定义函数
def greet(name):
return "Hello, " + name
message = greet("Alice") # 调用函数

# 面向对象编程(OOP)
# 定义类
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print("Woof!")
my_dog = Dog("Buddy") # 创建对象
my_dog.bark() # 调用对象方法

异常处理

1
2
3
4
5
6
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
finally:
print("This will be executed no matter what")

文件操作

1
2
3
4
5
6
7
8
# 写入文件
with open("example.txt", "w") as file:
file.write("Hello, Python!")

# 读取文件
with open("example.txt", "r") as file:
content = file.read()
print(content)

Pandas

Pandas 是一个强大的数据分析库,主要用于数据处理和分析。它提供了两种主要的数据结构:SeriesDataFrame

  • Series 是一个一维标记数组,可以保存任何数据类型。它由两个主要部分组成:索引(index)和数据(data)。
  • DataFrame 是一个二维表格,类似于 Excel 表格或 SQL 表。它由行索引、列索引和数据组成。
    数据组织:DataFrame 以表格的形式组织数据,包括多个列,每一列可以包含不同的数据类型(整数、浮点数、字符串等)。
    索引:每个行和列都有一个标签索引。行索引表示 DataFrame 中的每个数据行,列索引表示 DataFrame 中的每个数据列。
    :DataFrame 的每一列是一个 Pandas Series 对象,这意味着它们可以包含相同类型的数据。你可以将每一列视为一个数据字段,类似于数据库表中的列。 下面是一个示例 DataFrame 的结构:
    1
    2
    3
    4
    5
    6
    |    | Name     | Age | City       |
    |----|----------|-----|------------|
    | 0 | Alice | 25 | Niu York | -- 行索引(0, 1, 2, 3)标识每一行的位置
    | 1 | Bob | 30 | Los Angeles| -- 列索引(Name, Age, City)表示不同的数据字段
    | 2 | Carol | 28 | Chicago | -- 每一列(Name, Age, City)都包含相应的数据
    | 3 | David | 22 | Houston | -- 每一列都是一个 Pandas Series,包含相同类型的数据
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import pandas as pd
    import numpy as np
    s = pd.Series([1, 3, 5, np.nan, 6, 8]) # 创建一个 Series
    df = pd.DataFrame({ # 创建一个 DataFrame
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'San Francisco', 'Los Angeles']
    })
    df = pd.DataFrame(columns=, data=) # 指定创建 DataFrame 的列索引和其中的数据

    for index, row in df.iterrows(): # 遍历DataFrame的每一行
    print(f"Index: {index}, Name: {row['Name']}, Age: {row['Age']}, City: {row['City']}")
    # Index: 0, Name: Alice, Age: 25, City: New York...

    # 将 DataFrame 对象保存为 CSV 文件
    # sep 表示数据字段之间的分隔符,header 表示是否将列名写入文件,index 表示是否写入行索引。
    df.to_csv('data.txt', sep = ' ', index = False, header = False)
    # 从 CSV、Excel文件读取数据
    df = pd.read_csv('data.csv')
    df = pd.read_excel('data.xlsx')

Numpy

numpy(Numerical Python的缩写)是一个用于科学计算的强大Python库。以下是一些 numpy 的主要功能和用法:

  1. 多维数组: numpy 提供了ndarray对象,是一个多维数组,用于存储同类型的元素。
    1
    2
    3
    import numpy as np
    # 创建一个numpy数组
    arr = np.array([1, 2, 3, 4, 5])
  2. 数组操作: numpy 提供了许多对数组进行操作的函数,包括数学、逻辑、形状操作等。
    1
    2
    3
    4
    # 数组的数学运算
    result = arr + 2
    # 数组形状操作
    reshaped_arr = arr.reshape(5, 1)
  3. 矩阵操作: numpy 具有广泛的矩阵操作,包括矩阵乘法、转置等。
    1
    2
    3
    4
    matrix_a = np.array([[1, 2], [3, 4]])
    matrix_b = np.array([[5, 6], [7, 8]])
    # 矩阵乘法
    result_matrix = np.dot(matrix_a, matrix_b)
  4. 数学函数: numpy 包括大量的数学函数,用于三角函数、对数、指数等。
    1
    2
    3
    x = np.array([0, 1, 2, 3, 4])
    # 求sin(x)
    sin_values = np.sin(x)
  5. 随机数生成: numpy 提供了生成随机数的函数。
    1
    random_numbers = np.random.rand(5)  # 生成5个在[0, 1)范围内的随机数

Python爬虫

反爬虫策略

  • 设置合理的请求头。
    1
    2
    3
    headers = {   # 伪装浏览器请求头
    'Cookie': 'ispeed_lsm=2; baikeVisitId=b84d4a50-436c-4e0f-9e29-dc2393e9cdca; COOKIE_SESSION=6_1_8_5_10_9_1_0_7_5_0_3_33002_0_2_0_1650022038_1650022034_1650022036%7C8%230_1_1650022030%7C1; BD_UPN=1126314751; BD_HOME=1; BD_CK_SAM=1; H_PS_645EC=89b2Pt9WoxiJHIC80g9QL3FIo7tdoc9Z9Gm9Nd6gkOPipOmTDtckrFlLxEpchFYkItCM; BAIDUID=FD56AC9125756B81A0E4EB7A60F27700:FG=1; BIDUPSID=FD56AC9125756B81E8CE802CC99B8074; PSTM=1648004100; BDUSS=Jpc2d4NGIwdzRCNVFTR0xNeS1IYXBLNTQwfjhzRnl3Z0xRSlZJTDhZeU1ibnhpRVFBQUFBJCQAAAAAAAAAAAEAAAAnQDHOyfq77rXDd2luZHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIzhVGKM4VRiT2; H_PS_PSSID=36426_31660_35912_36167_34584_35979_36055_36235_26350; BA_HECTOR=ak20800k8kag8h8le71h8646s0q; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; delPer=0; PSINO=6',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36'}
  • 使用代理IP。
  • 限制请求频率,避免被封IP。
    1
    2
    sleep_time = random.uniform(0, 2)
    time.sleep(sleep_time)
  • 处理验证码和登录等复杂场景。

网络请求库:

  • requests库:用于发送HTTP请求,获取网页内容。
    1
    2
    3
    4
    5
    import requests
    # url_base = 'http://leo/index.phtml?reportdate={year}&quarter={quarter}&p={page}'
    # url = url_base.format(year=iyear, quarter=iquarter, page=page) # 替换url模板中的占位符
    response = requests.get(url=url, headers=self.headers)
    res = response.content.decode() # 获取服务器响应的内容,将其解码成字符串

HTML解析库:

  • BeautifulSoup:用于解析HTML文档,提取所需信息。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(res, 'html.parser') # 解析 HTML 内容
    first_paragraph = soup.find('p') # 查找第一个<p>标签
    script = soup.find(id=tag_id) # 找到具有指定 id 属性的标签
    # script.string.replace_with(new_string) # 替换标签内容
    # script.append(new_tag) # 在标签内追加新标签
    # script.extract() # 从文档中删除标签
    text = script.text # 获取标签内容
    # json_str = re.findall(r'\[.+\]', text)[0] # 用正则表达式 re 从 text 中查找一个或多个包含 JSON 数据的字符串的第一个匹配项
    # data = json.loads(json_str) # 把json格式的字符串转换为Python类型
    script1 = soup.find('p', class_='paragraph') # 查找带有指定class的<p>标签
    script2 = soup.find('a', href='https://...') # 查找带有指定属性的<a>标签
    labels = soup.find_all('a', attrs={'href': True}) # 模糊搜索HTML代码中所有含href属性的<a>标签
  • lxml:使用类似 XPath 的功能解析HTML文档。
    1
    2
    3
    4
    from lxml import html
    tree = html.fromstring(html_doc)
    paragraphs = tree.xpath('//p') # 使用 XPath 表达式查找<p>标签
    paragraphs_with_class = tree.xpath('//p[@class="paragraph"]') # 使用 XPath 表达式查找具有指定class属性值的<p>标签

数据存储:

  • 文件存储:将爬取的数据保存为文本文件、CSV文件等。
  • 数据库:使用SQLite、MySQL、MongoDB等数据库存储数据。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    def load(self, path):
    with open(path, encoding='utf-8') as fp: # 加载存储在JSON文件中的数据, 指定文件为UTF-8编码
    data = json.load(fp)
    return data
    def save(self, data, path):
    with open(path, 'w', encoding='utf-8') as fp: # 以json格式保存, 最近一日各国疫情数据
    json.dump(data, fp, ensure_ascii=False)

    def baidu_search(v_result_file): # 保存csv数据
    df = pd.DataFrame(
    {
    '关键字': kw_list, '页码': page_list, '标题': title_list, '百度链接': href_list,
    '真实链接': real_url_list, '更新时间': time_list, '简介': desc_list,
    '网站名称': site_list,
    }
    )
    if os.path.exists(v_result_file):
    header = None # 已存在的csv文件保存时不用加标头
    else:
    # 创建新文件时,设置csv文件标头
    header = ['关键词', '页码', '标题', '百度链接', '真实链接', '更新时间', '简介', '网站名称']
    df.to_csv(v_result_file, mode='a+', index=False, header=header, encoding='utf_8_sig')
    print('结果保存成功:{}'.format(v_result_file))

爬虫框架

  • Scrapy:一个强大的Python爬虫框架,提供了高级功能如异步处理、中间件等。
    1
    scrapy startproject myproject

动态网页爬取

  • 使用Selenium或Headless浏览器模拟浏览器行为。
  • 处理JavaScript渲染的页面。

Anaconda

  1. 利用 Anaconda,创建不同版本的虚拟环境,配置不同的包(如不同版本的 Pytorch),以管理不同的项目。
  2. 用 Pycharm 打开项目时,点击添加解释器 —> 添加本地解释器,选择该项目对应的 conda 虚拟环境下,该虚拟环境的 python 解释器。选择使用这个虚拟环境对应的编辑器,就是选择了使用这个环境运行项目,使用这个环境中配好的包等等。
  3. 所以要注意终端使用的是哪个编辑器,是否与当前项目使用的编辑器匹配。否则 pip install 把包装到一个虚拟环境,而当前项目运行在另一个虚拟环境中,便无法 import 已安装的包。

新建虚拟环境

打开Anaconda Prompt,创建一个名字为py36的python版本为3.6的虚拟环境(默认地址已改成D:\anaconda3\envs),并查看已有环境:

1
2
3
4
5
6
7
(base) C:\Users\cf>conda create -n py36 python=3.6
Proceed ([y]/n)? y
(base) C:\Users\cf>conda env list
# conda environments:
#
base * D:\anaconda3
py36 D:\anaconda3\envs\py36

激活(切换)环境,并查看该环境下已有包:

1
2
(base) C:\Users\cf>conda activate py36
(py36) C:\Users\cf>pip list

装包

方法1:在 Anaconda Prompt 中进入该环境后,执行 conda install … 或 pip install …(需要关闭代理)
方法2:在 Pycharm的terminal(终端),执行安装指令(此时所处的是 Pycharm终端 的环境(不一定是此时加载的项目的环境))

1
2
3
4
5
# 其他pip指令
pip list # 列出所有已安装的pip包
pip install package_name==desired_version # 安装指定版本的Python包
pip install --target=... package_name # 指定pip install包的路径
pip show package_name # 查看安装好的包的信息

Jupyter Notebook

以任意行为块,便于代码阅读和测试修改。 在一个环境中安装 jupyter notebook 后,运行:

1
(py36) C:\Users\cf>jupyter notebook        

在浏览器打开8888端口使用 http://localhost:8888/?token=7e39781c1e364fa7a5ee95ef290ffa92eb0caef0c19aaad8


Django

Django是一个基于Python的开源Web应用框架,它遵循 MTV 框架,与传统的 MVC 有一些区别,但是其基本思想和流程是类似的,旨在简化Web开发过程,提高开发效率,同时保持代码的可读性和可维护性。

MTV 架构

  1. Model(模型):负责处理数据逻辑,定义数据库模型(ORM),进行数据的增删改查操作。
  2. Template(模板):负责呈现用户界面,包含 HTML、CSS、JavaScript 等前端代码,展示数据给用户。
  3. View(视图): 处理用户请求,根据请求调用适当的模型和模板,返回响应给用户。

MTV 流程

  1. 用户发起请求Request到 Django 服务器。
  2. Django 的 URL 配置根据请求的 URL 路径找到对应的视图(View)函数。
  3. 视图函数处理请求,可能需要进行数据库操作,调用模型(Model)获取数据。
  4. 视图函数将获取的数据传递给模板(Template),并渲染生成最终的 HTML 页面。
  5. 服务器将生成的 HTML 页面作为响应Response返回给用户。

目录结构

  1. 项目目录:包含整个 Django 项目的配置和管理文件,settings.py、urls.py、wsgi.py(WSGI 入口)、asgi.py(ASGI 入口)等。
  2. 应用目录:包含具体的应用程序代码和文件,models.py(模型)、views.py(视图)、urls.py(应用URL配置)、templates/ 等。
  3. 静态文件目录: 存放静态资源文件,如 CSS、JavaScript、图片等。默认路径是项目目录下的 static/ 文件夹。
  4. 模板目录: 存放 HTML 模板文件。 默认路径是应用目录下的 templates/ 文件夹。
  5. 数据库文件:默认情况下,Django 使用 SQLite 作为默认数据库,并将数据库文件存放在项目目录下的 db.sqlite3 文件中。
    一个Django项目(project)就是一个基于Django的Web应用,一个Django项目包含一组配置和若干个Django应用
    一个Django应用(blog)就是一个可重用的Python软件包,每个应用可以自己管理模型、视图、模板、路由和静态文件等

几个入门命令

  • 文件路径cmd
    1
    2
    3
    4
    5
    6
    cd E:/.../mainproject                  # 一定要把终端路径切换成项目根目录!!!
    django-admin startproject mainproject # 创建项目,生成工程目录
    python manage.py startapp firstWEB # 创建APP(进入工程目录/IDE console)
    python manage.py makemigrations # 创建库表(进入工程目录/IDE console)
    python manage.py migrate # 执行库表建立(进入工程目录/IDE console)
    python manage.py runserver # 启动项目(进入IDE console)
  • 几个入门设置(settings.py):Django 框架时间设置,Django APP添加,Templates目录设置(在APP日录下,需要独立建立)

HelloWorld

  • 实现一个请求view,访问 主项目project 中的 blog应用 的hello_world接口
    1. 编写应用请求 project/blog/views.py
      1
      2
      def hello_world(request):
      return HttpResponse("2323")
    2. 配置应用路由 project/blog/urls.py
      1
      2
      3
      urlpatterns = [
      path('hello_world', blog.views.hello_world)
      ]
    3. 配置项目路由 project/project/urls.py
      1
      2
      3
      4
      5
      urlpatterns = [
      path('admin/', admin.site.urls),
      # 如果url中含有 'blog',就转发到应用层面的路由处理
      path('blog/', include('blog.urls'))
      ]
    4. 添加blog应用到项目配置中 project/project/settings.py
      1
      2
      3
      4
      INSTALLED_APPS = [
      # ...
      'blog.apps.BlogConfig', # 创建APP时自动创建
      ]
  • 请求转发流程 http://127.0.0.1:8000/blog/
    浏览器 –(项目路由)–> Blog App –> view.py –(应用路由)–> hello_world函数 –> 浏览器

模型层

  • 模型层是什么?
    • 模型层:位于Django视图层和数据库之间, Python对象和数据库表之间转换
    • 模型层作用:屏蔽不同数据库之间的差异, 开发者更加专注于业务逻辑的开发, 提供很多便捷工具有助开发
    • 模型层配置 project/project/settings.py
      1
      2
      3
      4
      5
      6
      DATABASES = {
      'default': {
      'ENGINE': 'django.db.backends.sqlite3', # 自带的数据库
      'NAME': BASE_DIR / 'db.sqlite3',
      }
      }
  • 模型 Model:Model是数据库表的抽象表示。
    • 每个模型都继承自django.db.models.Model类,并定义了一组字段(Field),这些字段对应于数据库表中的列。
      1
      2
      3
      4
      5
      6
      7
      8
      from django.db import models  

      class Author(models.Model): # Author模型有两个字段:name和email
      name = models.CharField(max_length=100)
      email = models.EmailField()
      class Book(models.Model): # Book模型有一个title字段和一个指向Author模型的外键
      title = models.CharField(max_length=200)
      author = models.ForeignKey(Author, on_delete=models.CASCADE)
    • 一旦你定义了模型,Django就会自动为你生成一个数据库表(除非你明确告诉它不要这样做)。然后,你可以使用Django的ORM(对象关系映射)API来查询、创建、更新和删除数据库中的记录。以下是一些基本示例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      # 获取所有作者  
      authors = Author.objects.all()
      # 获取标题为"Django教程"的书
      book = Book.objects.get(title="Django教程")
      # 创建一个新作者
      new_author = Author.objects.create(name="John Doe", email="john@example.com")
      # 创建一个新书,并将其与作者关联
      new_book = Book.objects.create(title="Django入门", author=new_author)
      # 获取并更新一本书的标题
      book = Book.objects.get(title="Django教程")
      book.title = "Django进阶"
      book.save()
      # 删除一本书
      book = Book.objects.get(title="Django进阶")
      book.delete()
  • 迁移 Migrations:Django框架中用于管理数据库模式更改的一种强大工具。
    • 当你更改Django模型(Model)时(例如添加、删除或修改字段),Django能够自动计算出需要应用到数据库中的更改,并将这些更改保存为迁移文件。然后,你可以使用Django的迁移命令将这些更改应用到数据库中。
    • 创建迁移文件
      1
      python manage.py makemigrations  # IDE console
    • 运行迁移文件 同步sqlite3数据库
      1
      python manage.py migrate  # IDE console
  • Django shell操作
    • Django shell:继承Django项目环境,用于交互的Python编程,方便快捷
    • 新建文章:IDE console操作
      1
      python manage.py shell  # 进入 Djungo shell
      1
      2
      3
      4
      5
      6
      7
      >>> from blog.models import Article  # 导入模型
      >>> a = Article() # 创建文章
      >>> a.title = 'Test Django Shell'
      >>> a.brief = '...'
      >>> a.save() # 保存文章
      >>> articles = Article.objects.all() # 获取文章
      >>> print(articles[0].title)
  • Django Admin模块
    • Django的后台管理工具,简化Djungo shell的使用;直接读取定义的模型元数据,提供强大的管理使用页面
    • Django的使用
      1
      python manage.py createsuperuser  # 创建管理员用户:caif / cxxxxxxx
      1
      2
      3
      from .models import Article

      admin.site.register(Article) # 将模型注册到admin模块 project/blog/admin.py
      登录页面进行管理:http://127.0.0.1:8000/admin/login/?next=/admin/, 选择模型,进行创建、修改、删除对象操作
  • Model数据返回页面
    1. 编写应用请求 project/blog/views.py
      1
      2
      3
      4
      5
      6
      from blog.models import Article

      def article_content(request): # 就是返回处理过的model数据
      article = Article.object.all()[0] # 从sqlite3中获取对应模型的数据
      ans_str = article.title + ...
      return HttpResponse(ans_str)
    2. 配置应用路由 project/blog/urls.py
    3. 配置项目路由 project/project/urls.py
    4. 添加blog应用到项目配置中 project/project/settings.py

连接本地MySQL

  • 默认情况下,Django连接的是自己带的sqlite数据库。好处是方便,不需要远程连接,打包项目挪到其他电脑上安装一下依赖一会就跑起来了,但是缺点就是,可能会出现各种莫名其面的问题,所以,尽可能在开始的时候,就配置上连接Mysql。
  • Django 连接 MySQL:
    • 安装 Python 访问 MySQL的 客户端模块
      1
      pip install mysqlclient  # Django官方已不建议使用pymysql库,而是改用mysqlclient
    • 修改 Django项目文件夹下的settings.py文件:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      DATABASES = {
      'default': {
      'ENGINE': 'django.db.backends.mysql', # 使用MySQL引擎
      'NAME': 'HKStock', # 数据库名称
      'USER': 'root', # 数据库用户名
      'PASSWORD': '123456', # 数据库密码
      'HOST': 'localhost', # 数据库主机(如果在本地)
      'PORT': '3306', # 数据库端口(默认为3306)
      }
      }
    • Pycharm 连接 MySQL:点击 Pycharm右上角 database -> “+” -> source -> MySQL,输入数据库名称、用户、密码连接成功
    • 修改项目文件夹下的__init.py文件:要替换默认的数据库引擎,在项目文件夹下的__init__.py 添加以下内容。
      1
      2
      3
      import pymysql

      pymysql.install_as_MySQLdb()
  • 定义模型 Model:将数据库 SQL 映射到面向对象的 Python 中来,使得你可以在 Django 中像操作普通对象一样操作数据库。
  • 迁移 Migrations:定义好了Model,数据库中的表并不会神奇的出现,你还需要把模型转化为对数据库的操作,这就是迁移。
    当你更改Django模型(Model)时(例如添加、删除或修改字段)Django能够自动计算出需要应用到数据库中的更改,并将这些更改保存为迁移文件。然后,你可以使用Django的迁移命令将这些更改应用到数据库中。
  • 新model迁移:
    1. 定义模型(mainapp/models.py)
      1
      2
      3
      class pen(models.Model):
      price = models.IntegerField()
      color = models.CharField(default='black', max_length=20)
    2. 创建迁移文件:指令执行完毕后会生成 mainapp/migrations/0001_initial.py 文件。Django 不会检查你的数据库,而是根据目前的模型的状态,创建一个操作列表,使项目状态与模型定义保持最新。
      1
      python manage.py makemigrations
    3. 运行迁移文件:打开数据库可以看到多了 mainapp_pen 表,并且里面的字段和模型是完全匹配的。插入一些数据。
      1
      python manage.py migrate 
    4. 功能demo
      1
      2
      3
      4
      5
      6
      # 编写url:在项目文件夹 datasite/urls.py
      from mainapp import views

      urlpatterns = [
      path('pen', views.pen) # 配置项目url即可,无需配置应用url
      ]
      1
      2
      3
      4
      5
      6
      7
      # 编写视图(views):在应用文件夹web/views.py,操作model从MySQL中获取数据
      from .models import Pen

      def pen(request):
      pen = Pen.objects.all()
      # 结合html(templates/pen.html)展示数据
      return render(request,"pen.html",{"pen_queryset":pen_queryset})
    5. 启动web:python manage.py runserver
    6. 发送请求:http://127.0.0.1:8000/pen
  • 操作MySQL中已有的表:
    1. 配置Django的数据库设置(项目级settings.py),确保已安装MySQL客户端并且设置好__init__.py文件。
    2. 创建Django模型:尽管数据库表已经存在,但仍需为这些表创建Django模型。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      from django.db import models  

      class Student(models.Model):
      name = models.CharField(max_length=255)
      code = models.CharField(max_length=255)

      class Meta:
      db_table = 'mainapp_student' # 数据库中的实际表名,注意这里应该与你的数据库表名一致
      managed = False # 指示Django该模型对应于现有的数据库表,不由Django迁移管理
    3. 同步Django模型与数据库:只需python manage.py makemigrations,无需python manage.py migrate ??
    4. 在Django中操作数据库表:使用Django的ORM API来查询、创建、更新和删除数据库中的记录了。

视图与模版

  • 使用Bootstrap实现静态博客页面
    • 在 project/blog/template 下创建 index.html
      1
      2
      3
      4
      5
      <!-- 在 header 引入 -->
      <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
      <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
      <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
      <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <!-- 静态代码块 -->
      <div class="container page-header">
      <h1 class="text-center mb-4">博客标题</h1>
      </div>
      <div class="container page-body">
      <div class="col-lg-9">
      <!-- 博客详情1, 2, ... -->
      </div>
      <div class="col-lg-3">
      <!-- 博客链接1, 2, ... -->
      </div>
      </div>
  • Django模板系统
    • 一个类似html的文本文件,结合view,实现动态页面。模板语法:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      <!DOCTYPE html>
      <html>
      <head>
      <title>Blog Post</title>
      </head>
      <body>
      <h1>{{ post.title }}</h1>

      {% if user.is_authenticated %}
      <a href="{% url 'logout' %}">Logout</a>
      {% else %}
      <a href="{% url 'login' %}">Login</a>
      {% endif %}

      <ul>
      {% for comment in post.comments.all %}
      <li>{{ comment.content }} - {{ comment.author.username }}</li>
      {% endfor %}
      </ul>
      </body>
      </html>
    • 使用模板系统渲染博客页面
      在 Django 中,模板文件通常存储在每个应用的 /templates目录下。在应用view中渲染这个模板文件,并传递上下文数据:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      from django.shortcuts import render
      from datetime import datetime

      # home_view 视图函数渲染了 home.html 模板,并向模板传递了两个变量:name 和 date
      def home_view(request):
      context = {
      'name': 'My Django Website',
      'date': datetime.now(),
      }
      return render(request, 'home.html', context)

: (


ECharts

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
https://echarts.apache.org

  • 在项目中引入echarts
    • mainapp/static/assets/js/ 目录中保存 echarts.js
    • mainapp/templates/xx.html 文件中引入 echarts.js
    • 示例:一个简单柱状图
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="utf-8" />
      <title>ECharts</title>
      <!-- 引入刚刚下载的 ECharts 文件 -->
      <script src="echarts.js"></script>
      </head>
      <body>
      <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
      <div id="main" style="width: 600px;height:400px;"></div>
      <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById('main'));
      // 指定图表的配置项和数据
      var option = {
      xAxis: {
      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      },
      yAxis: {},
      series: [
      {
      type: 'bar',
      data: [23, 24, 18, 25, 27, 28, 25]
      }
      ]
      };
      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
      </script>
      </body>
      </html>
  • 传入数据渲染echarts模版:
    1. 在view函数中准备数据,比如一个Python列表或字典;通过渲染函数(render())将数据传递到模板中;
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      from django.shortcuts import render  

      def chart_view(request):
      # 准备数据
      x_axis_data = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      y_axis_data = [23, 24, 18, 25, 27, 28, 55]

      # 将数据传递给模板
      context = {
      'x_axis_data_json': json.dumps(x_axis_data), # JSON 字符串形式的数据
      'y_axis_data_json': json.dumps(y_axis_data),
      }
      return render(request, '2.html', context)
    2. 复制示例模版from https://echarts.apache.org/examples/zh/index.html, 使用 Django模板标签将数据嵌入到 js代码中
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      <!DOCTYPE html>  
      <html>
      <head>
      <meta charset="utf-8" />
      <title>ECharts</title>
      <!-- 引入ECharts文件,确保路径正确 -->
      <script src="echarts.js"></script>
      </head>
      <body>
      <div id="main" style="width: 600px;height:400px;"></div>
      <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById('main'));

      // 从 Django 模板上下文中取出数据,并转换为 JavaScript 数组
      var x_axis_data = JSON.parse('{{ x_axis_data_json|escapejs }}');
      var y_axis_data = JSON.parse('{{ y_axis_data_json|escapejs }}');

      // 指定图表的配置项和数据
      var option = {
      xAxis: {
      type: 'category',
      data: x_axis_data // 使用从 Django 传递的数据
      },
      yAxis: {
      type: 'value'
      },
      series: [
      {
      data: y_axis_data, // 使用从 Django 传递的数据
      type: 'bar'
      }
      ]
      };

      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
      </script>
      </body>
      </html>