签入版本
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
# 数据库与 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.elevue')
|
||||
|
||||
# 数据库地址
|
||||
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 连接配置,支持通过环境变量覆盖。软删除机制确保数据安全,所有查询自动过滤已删除记录。
|
||||
Reference in New Issue
Block a user