mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 04:46:26 +00:00
feat: 添加部门字段显示并优化用户界面
fix(service): 修复创建时编码重复检查问题 refactor(middleware): 优化CORS中间件配置 style(model): 更新用户模型默认性别值 perf(request): 增强前端请求错误处理 docs(cli): 改进命令行帮助文本 chore: 清理无用配置并更新依赖
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from sqlalchemy import ForeignKey, Integer, DateTime, Text
|
||||
from sqlalchemy import ForeignKey, Integer, DateTime, String, Text
|
||||
from sqlalchemy.ext.asyncio import AsyncAttrs
|
||||
from sqlalchemy.orm import relationship, DeclarativeBase, Mapped, declared_attr, mapped_column
|
||||
|
||||
@@ -27,30 +27,15 @@ class MappedBase(AsyncAttrs, DeclarativeBase):
|
||||
__abstract__ = True
|
||||
|
||||
|
||||
class ModelMixin(MappedBase):
|
||||
"""
|
||||
基础模型混合类
|
||||
"""
|
||||
# Mixin: 一种面向对象编程概念, 使结构变得更加清晰, `Wiki <https://en.wikipedia.org/wiki/Mixin/>`__
|
||||
class UserMixin(MappedBase):
|
||||
"""用户 Mixin 数据类"""
|
||||
__abstract__ = True
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment='主键ID')
|
||||
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, default=None, comment="备注/描述")
|
||||
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, comment='创建时间')
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, onupdate=datetime.now, comment='更新时间')
|
||||
created_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="创建人ID")
|
||||
updated_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="更新人ID")
|
||||
|
||||
|
||||
class CreatorMixin(ModelMixin):
|
||||
"""
|
||||
创建人混合类
|
||||
"""
|
||||
__abstract__ = True
|
||||
|
||||
# creator_id: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True, comment="创建人ID")
|
||||
creator_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="创建人ID")
|
||||
|
||||
@declared_attr
|
||||
def creator(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
|
||||
"""
|
||||
创建人关联关系(延迟加载,避免循环依赖)
|
||||
SQLAlchemy ORM 中的这些加载策略用于控制关联对象的加载行为,它们的主要区别如下:
|
||||
|
||||
@@ -64,7 +49,65 @@ class CreatorMixin(ModelMixin):
|
||||
8.immediate :立即加载,在主对象加载后立即执行额外查询获取关联数据,类似 select 但不延迟。
|
||||
9.write_only :专为写入优化,不允许读取关联数据,只可添加新记录,适合只写不读的场景。
|
||||
10.dynamic :返回动态查询对象而非实际结果集,允许进一步过滤和分页,适合处理大量关联数据。
|
||||
"""
|
||||
@declared_attr
|
||||
def created_by(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
|
||||
"""
|
||||
创建人关联关系(延迟加载,避免循环依赖)
|
||||
"""
|
||||
return relationship(
|
||||
"UserModel",
|
||||
primaryjoin=f"{cls.__name__}.creator_id == UserModel.id",
|
||||
lazy="selectin",
|
||||
foreign_keys=lambda: [cls.creator_id], # type: ignore
|
||||
viewonly=True,
|
||||
uselist=False # 明确指定返回单个对象
|
||||
)
|
||||
|
||||
@declared_attr
|
||||
def updated_by(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
|
||||
"""
|
||||
更新人关联关系(延迟加载,避免循环依赖)
|
||||
"""
|
||||
return relationship(
|
||||
"UserModel",
|
||||
primaryjoin=f"{cls.__name__}.creator_id == UserModel.id",
|
||||
lazy="selectin",
|
||||
foreign_keys=lambda: [cls.creator_id], # type: ignore
|
||||
viewonly=True,
|
||||
uselist=False # 明确指定返回单个对象
|
||||
)
|
||||
|
||||
|
||||
class DateTimeMixin(MappedBase):
|
||||
"""日期时间 Mixin 数据类"""
|
||||
__abstract__ = True
|
||||
|
||||
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, comment='创建时间')
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, onupdate=datetime.now, comment='更新时间')
|
||||
|
||||
|
||||
class ModelMixin(DateTimeMixin):
|
||||
"""
|
||||
基础模型混合类
|
||||
"""
|
||||
__abstract__ = True
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment='主键ID')
|
||||
uuid: Mapped[str] = mapped_column(String(64), unique=True)
|
||||
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, default=None, comment="备注/描述")
|
||||
|
||||
|
||||
class CreatorMixin(ModelMixin):
|
||||
"""
|
||||
创建人混合类
|
||||
"""
|
||||
__abstract__ = True
|
||||
|
||||
creator_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="创建人ID")
|
||||
|
||||
@declared_attr
|
||||
def creator(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
|
||||
# 其他模型保持原有配置
|
||||
return relationship(
|
||||
"UserModel",
|
||||
|
||||
@@ -20,14 +20,14 @@ from app.api.v1.module_system.params.service import ParamsService
|
||||
class CustomCORSMiddleware(CORSMiddleware):
|
||||
"""CORS跨域中间件"""
|
||||
def __init__(self, app: ASGIApp) -> None:
|
||||
CORSMiddlewareConfig: dict[str, Any] = {
|
||||
"allow_origins": settings.ALLOW_ORIGINS,
|
||||
"allow_methods": settings.ALLOW_METHODS,
|
||||
"allow_headers": settings.ALLOW_HEADERS,
|
||||
"allow_credentials": settings.ALLOW_CREDENTIALS,
|
||||
"expose_headers": settings.CORS_EXPOSE_HEADERS,
|
||||
}
|
||||
super().__init__(app, **CORSMiddlewareConfig)
|
||||
super().__init__(
|
||||
app,
|
||||
allow_origins=settings.ALLOW_ORIGINS,
|
||||
allow_methods=settings.ALLOW_METHODS,
|
||||
allow_headers=settings.ALLOW_HEADERS,
|
||||
allow_credentials=settings.ALLOW_CREDENTIALS,
|
||||
expose_headers=settings.CORS_EXPOSE_HEADERS,
|
||||
)
|
||||
|
||||
|
||||
class RequestLogMiddleware(BaseHTTPMiddleware):
|
||||
|
||||
Reference in New Issue
Block a user