django从入门到实战(四)——模型与数据库

1. 模型的定义与数据迁移

1.1 模型的定义

在 Django 中,模型是一个 Python 类,用于定义数据库中的数据结构。每个模型类对应数据库中的一张表,类的属性对应表中的字段。

示例

python 复制代码
from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=200)  # 标题
    content = models.TextField()                # 内容
    created_at = models.DateTimeField(auto_now_add=True)  # 创建时间
    updated_at = models.DateTimeField(auto_now=True)      # 更新时间

    def __str__(self):
        return self.title

参数说明

  • models.Model: 所有模型类都需要继承自 models.Model
  • CharField: 用于存储字符串,max_length 是必需的参数。
  • TextField: 用于存储长文本。
  • DateTimeField: 用于存储日期和时间,auto_now_addauto_now 分别表示在创建和更新时自动设置当前时间。

1.2 数据迁移

数据迁移是将模型的变化应用到数据库的过程。Django 提供了命令行工具来管理迁移。

步骤

  1. 创建迁移文件
bash 复制代码
python manage.py makemigrations
  1. 应用迁移
bash 复制代码
python manage.py migrate

1.3 开发自己的 ORM 框架

开发自己的 ORM 框架涉及创建一个类来映射数据库表,并实现基本的 CRUD 操作。以下是一个简单的示例:

python 复制代码
import sqlite3

class SimpleORM:
    def __init__(self, db_name):
        self.connection = sqlite3.connect(db_name)
        self.cursor = self.connection.cursor()

    def create_table(self, table_name, columns):
        columns_with_types = ', '.join([f"{name} {dtype}" for name, dtype in columns.items()])
        self.cursor.execute(f"CREATE TABLE IF NOT EXISTS {table_name} ({columns_with_types})")
        self.connection.commit()

    def insert(self, table_name, data):
        placeholders = ', '.join(['?'] * len(data))
        self.cursor.execute(f"INSERT INTO {table_name} VALUES ({placeholders})", tuple(data.values()))
        self.connection.commit()

    def fetch_all(self, table_name):
        self.cursor.execute(f"SELECT * FROM {table_name}")
        return self.cursor.fetchall()

    def close(self):
        self.connection.close()

参数说明

  • db_name: 数据库名称。
  • table_name: 表名。
  • columns: 字典,键为列名,值为数据类型。
  • data: 字典,键为列名,值为要插入的数据。

1.4 数据导入和导出

数据导入和导出可以通过 CSV 文件或其他格式进行。

导出示例

python 复制代码
import csv

def export_to_csv(data, filename):
    with open(filename, mode='w', newline='') as file:
        writer = csv.writer(file)
        writer.writerows(data)

导入示例

python 复制代码
def import_from_csv(filename):
    with open(filename, mode='r') as file:
        reader = csv.reader(file)
        return list(reader)

2. 数据表关系

在数据库中,表之间可以有不同的关系,主要包括:

  • 一对一关系:一个表中的一条记录对应另一个表中的一条记录。
  • 一对多关系:一个表中的一条记录可以对应另一个表中的多条记录。
  • 多对多关系:两个表中的记录可以相互对应多条记录。

示例

python 复制代码
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)  # 一对多关系

3. 数据表操作

3.1 增删改查(CRUD)

增加
python 复制代码
# 创建新博客
new_blog = Blog(title="My First Blog", content="This is the content.")
new_blog.save()
查询
python 复制代码
# 查询所有博客
all_blogs = Blog.objects.all()

# 查询特定博客
specific_blog = Blog.objects.get(id=1)
更新
python 复制代码
# 更新博客内容
specific_blog.content = "Updated content."
specific_blog.save()
删除
python 复制代码
# 删除博客
specific_blog.delete()

3.2 多表查询

使用 Django 的 ORM 可以轻松进行多表查询。

python 复制代码
# 查询某个作者的所有书籍
author_books = Book.objects.filter(author__name="Author Name")

4. 数据库与 SQL 语句

4.1 SQL 语句

SQL(结构化查询语言)用于与数据库交互。常用的 SQL 语句包括:

  • SELECT:查询数据。
  • INSERT:插入数据。
  • UPDATE:更新数据。
  • DELETE:删除数据。

4.2 数据库事务

事务是一组操作,要么全部成功,要么全部失败。Django 提供了事务管理的支持。

python 复制代码
from django.db import transaction

with transaction.atomic():
    # 执行多个数据库操作
    blog = Blog(title="Transactional Blog", content="Content")
    blog.save()
    # 其他操作

5. Django 如何制作多个数据库的链接和使用

在 Django 中,可以在 settings.py 中配置多个数据库。

示例配置

python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / "db.sqlite3",
    },
    'secondary': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

使用示例

python 复制代码
from django.db import connections

with connections['secondary'].cursor() as cursor:
    cursor.execute("SELECT * FROM my_table")
    rows = cursor.fetchall()

6. 动态创建模型和数据表

动态创建模型和数据表可以通过 Django 的 type 函数和 create_model 方法实现。

示例

python 复制代码
from django.db import models, connection

def create_dynamic_model(table_name):
    class Meta:
        db_table = table_name

    attrs = {'__module__': __name__, 'Meta': Meta}
    model = type(table_name.capitalize(), (models.Model,), attrs)
    return model

# 创建动态模型
DynamicModel = create_dynamic_model('dynamic_table')

7. MySQL 分表功能

MySQL 分表是将数据分散到多个表中,以提高性能和管理性。可以通过水平分表和垂直分表实现。

水平分表示例

假设我们有一个用户表,可以根据用户 ID 进行分表:

sql 复制代码
CREATE TABLE users_1 LIKE users;
CREATE TABLE users_2 LIKE users;

INSERT INTO users_1 SELECT * FROM users WHERE id % 2 = 0;
INSERT INTO users_2 SELECT * FROM users WHERE id % 2 = 1;

垂直分表示例

将用户表中的某些字段分到另一个表中:

sql 复制代码
CREATE TABLE user_profiles (
    user_id INT PRIMARY KEY,
    profile_picture VARCHAR(255),
    bio TEXT,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
相关推荐
这个DBA有点耶2 小时前
NULL不是空——数据库里最反直觉的设计,90%新人踩过的坑
数据库·mysql·代码规范
用户8356290780512 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
用户8356290780512 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
这个DBA有点耶4 小时前
AI写的SQL跑崩了生产库,这锅谁背?
数据库·人工智能·程序员
镜舟科技4 小时前
Databricks 再提 LTAP,AI 时代的数据底座为何重回大一统叙事?
数据库·架构·agent
Databend5 小时前
从湖仓升级为 Agent 时代的数据控制面,Snowflake 和 Databricks 有哪些布局
大数据·数据库·agent
ClouGence8 小时前
SQL Server CDC 能放到 Always On 备库读吗?一文讲透原理与实践
数据库·sql server
你好潘先生10 小时前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
Agent_大师10 小时前
WebSocket 行情重连成功,K线缺口不会自动消失
python
荣码10 小时前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python