199 lines
5.2 KiB
Markdown
199 lines
5.2 KiB
Markdown
# 数据库与 ORM
|
||
|
||
<!-- Copyright (c) 2021-2026 小蚂蚁云团队 版权所有 -->
|
||
|
||
:::tip 说明
|
||
项目使用 Django ORM 作为数据库访问层,数据库连接配置位于 `config/env.py` 和 `application/settings.py`。默认使用 MySQL 数据库,通过 `django.db.backends.mysql` 引擎连接。
|
||
:::
|
||
|
||
## 数据库配置
|
||
|
||
### 环境变量(config/env.py)
|
||
|
||
```python
|
||
# 数据库引擎,默认 MySQL
|
||
DATABASE_ENGINE = os.getenv('DATABASE_ENGINE', "django.db.backends.mysql")
|
||
|
||
# 数据库名称
|
||
DATABASE_NAME = os.getenv('DATABASE_NAME', 'djangoadmin.django.antdvue')
|
||
|
||
# 数据库地址
|
||
DATABASE_HOST = os.getenv('DATABASE_HOST', "127.0.0.1")
|
||
|
||
# 数据库端口
|
||
DATABASE_PORT = os.getenv('DATABASE_PORT', 3306)
|
||
|
||
# 数据库用户名
|
||
DATABASE_USER = os.getenv('DATABASE_USER', 'root')
|
||
|
||
# 数据库密码
|
||
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD', 'root')
|
||
|
||
# 数据表前缀
|
||
DATABASE_PREFIX = os.getenv('DATABASE_PREFIX', "django_")
|
||
```
|
||
|
||
### Django Settings(application/settings.py)
|
||
|
||
```python
|
||
DATABASES = {
|
||
"default": {
|
||
"ENGINE": env.DATABASE_ENGINE,
|
||
"NAME": env.DATABASE_NAME,
|
||
"USER": env.DATABASE_USER,
|
||
"PASSWORD": env.DATABASE_PASSWORD,
|
||
"HOST": env.DATABASE_HOST,
|
||
"PORT": env.DATABASE_PORT,
|
||
}
|
||
}
|
||
```
|
||
|
||
## MySQL 引擎配置
|
||
|
||
项目默认使用 `django.db.backends.mysql` 引擎,需要安装 `mysqlclient` 或 `PyMySQL`:
|
||
|
||
```bash
|
||
# 方式一:mysqlclient(推荐,C 扩展,性能更好)
|
||
pip install mysqlclient
|
||
|
||
# 方式二:PyMySQL(纯 Python,兼容性更好)
|
||
pip install PyMySQL
|
||
```
|
||
|
||
如果使用 PyMySQL,需要在 `application/__init__.py` 中添加:
|
||
|
||
```python
|
||
import pymysql
|
||
pymysql.install_as_MySQLdb()
|
||
```
|
||
|
||
## 数据表前缀
|
||
|
||
所有业务数据表自动添加 `DATABASE_PREFIX` 前缀(默认 `django_`),便于多应用共存:
|
||
|
||
```python
|
||
# utils/common.py
|
||
def get_table_name(base_name):
|
||
"""获取带前缀的表名"""
|
||
prefix = getattr(settings, 'DATABASE_PREFIX', '')
|
||
return f"{prefix}{base_name}"
|
||
```
|
||
|
||
## ORM 查询模式
|
||
|
||
### 基础查询
|
||
|
||
```python
|
||
from application.example.models import Example
|
||
|
||
# 查询未删除的记录(软删除)
|
||
queryset = Example.objects.filter(is_delete=False)
|
||
|
||
# 条件过滤
|
||
queryset = queryset.filter(name__contains=name) # 模糊查询
|
||
queryset = queryset.filter(status=status) # 精确匹配
|
||
queryset = queryset.order_by("sort") # 排序
|
||
```
|
||
|
||
### 分页查询
|
||
|
||
```python
|
||
from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage, EmptyPage
|
||
|
||
paginator = Paginator(queryset, page_size)
|
||
try:
|
||
page_list = paginator.page(page_no)
|
||
except (PageNotAnInteger, InvalidPage, EmptyPage):
|
||
page_list = paginator.page(1)
|
||
|
||
# 构建分页数据
|
||
page_data = {
|
||
'records': [item for item in page_list],
|
||
'total': paginator.count,
|
||
'size': page_size,
|
||
'current': page_no,
|
||
'pages': paginator.num_pages,
|
||
}
|
||
```
|
||
|
||
### 创建记录
|
||
|
||
```python
|
||
Example.objects.create(
|
||
name="示例",
|
||
status=1,
|
||
create_user=get_username(request),
|
||
update_user=get_username(request),
|
||
)
|
||
```
|
||
|
||
### 更新记录
|
||
|
||
```python
|
||
instance = Example.objects.filter(id=instance_id, is_delete=False).first()
|
||
if instance:
|
||
instance.name = "新名称"
|
||
instance.update_user = get_username(request)
|
||
instance.save()
|
||
```
|
||
|
||
### 批量更新(逻辑删除)
|
||
|
||
```python
|
||
Example.objects.filter(id__in=id_list, is_delete=False).update(is_delete=True)
|
||
```
|
||
|
||
## 软删除机制
|
||
|
||
所有业务模型继承 `BaseModel`,包含 `is_delete` 字段。所有查询都过滤 `is_delete=False`,删除操作为逻辑删除:
|
||
|
||
```python
|
||
# application/models.py
|
||
class BaseModel(models.Model):
|
||
id = models.BigAutoField(primary_key=True)
|
||
create_user = models.CharField(max_length=64, default='', null=True, blank=True)
|
||
create_time = models.DateTimeField(auto_now_add=True)
|
||
update_user = models.CharField(max_length=64, default='', null=True, blank=True)
|
||
update_time = models.DateTimeField(auto_now=True)
|
||
is_delete = models.BooleanField(default=False)
|
||
|
||
class Meta:
|
||
abstract = True
|
||
```
|
||
|
||
## 缓存配置(Redis)
|
||
|
||
Redis 用于 JWT Token 黑名单和权限缓存:
|
||
|
||
```python
|
||
# application/settings.py
|
||
CACHES = {
|
||
"default": {
|
||
"BACKEND": "django_redis.cache.RedisCache",
|
||
"LOCATION": f"redis://{env.REDIS_HOST}:{env.REDIS_PORT}/{env.REDIS_DB}",
|
||
"OPTIONS": {
|
||
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||
"PASSWORD": env.REDIS_PASSWORD if env.REDIS_PASSWORD else None,
|
||
"SOCKET_CONNECT_TIMEOUT": 5,
|
||
"SOCKET_TIMEOUT": 5,
|
||
"CONNECTION_POOL_KWARGS": {"max_connections": 100},
|
||
"IGNORE_EXCEPTIONS": True,
|
||
},
|
||
"KEY_PREFIX": "djangoadmin",
|
||
}
|
||
}
|
||
```
|
||
|
||
Redis 配置(config/env.py):
|
||
|
||
```python
|
||
REDIS_HOST = os.getenv('REDIS_HOST', '127.0.0.1')
|
||
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
|
||
REDIS_PASSWORD = os.getenv('REDIS_PASSWORD', '123456')
|
||
REDIS_DB = int(os.getenv('REDIS_DB', 0))
|
||
```
|
||
|
||
## 总结
|
||
|
||
数据库会话管理由 Django ORM 自动处理,每个请求自动管理数据库连接的生命周期。通过 `config/env.py` 集中管理数据库和 Redis 连接配置,支持通过环境变量覆盖。软删除机制确保数据安全,所有查询自动过滤已删除记录。
|