File size: 3,223 Bytes
b4f2238 | 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | """
Schema 基类和 Mixin
提供通用的字段解析方法,减少重复代码
"""
from datetime import datetime
from typing import Any, cast
from django.utils import timezone
class TimestampMixin:
"""
时间戳字段解析 Mixin
为 Schema 提供统一的时间字段处理
"""
@classmethod
def _resolve_datetime(cls, value: Any) -> datetime | None:
"""
统一处理 datetime 字段,转换为本地时间
Args:
value: datetime 对象或 None
Returns:
本地化的 datetime 或 None
"""
if value is None:
return None
try:
return timezone.localtime(value)
except (TypeError, AttributeError, ValueError):
return cast(datetime | None, value)
@classmethod
def _resolve_datetime_iso(cls, value: Any) -> str | None:
"""
统一处理 datetime 字段,转换为 ISO 格式字符串
Args:
value: datetime 对象或 None
Returns:
ISO 格式字符串或 None
"""
if value is None:
return None
try:
local_time = timezone.localtime(value)
return local_time.isoformat()
except (TypeError, AttributeError, ValueError):
return value.isoformat() if hasattr(value, "isoformat") else str(value)
class DisplayLabelMixin:
"""
显示标签解析 Mixin
为 choices 字段提供统一的 label 获取方法
"""
@classmethod
def _get_display(cls, obj: Any, field_name: str) -> str | None:
"""
获取 choices 字段的显示值
Args:
obj: Model 实例
field_name: 字段名
Returns:
显示值或 None
"""
try:
getter = getattr(obj, f"get_{field_name}_display", None)
if getter:
return cast(str | None, getter())
return getattr(obj, field_name, None)
except AttributeError:
return None
class FileFieldMixin:
"""
文件字段解析 Mixin
为 FileField 提供统一的 URL 和路径获取方法
"""
@classmethod
def _get_file_url(cls, file_field: Any) -> str | None:
"""
获取文件的 URL
Args:
file_field: FileField 实例
Returns:
文件 URL 或 None
"""
if not file_field:
return None
try:
return cast(str | None, file_field.url)
except (AttributeError, ValueError):
return None
@classmethod
def _get_file_path(cls, file_field: Any) -> str | None:
"""
获取文件的路径
Args:
file_field: FileField 实例
Returns:
文件路径或 None
"""
if not file_field:
return None
try:
return cast(str | None, file_field.path)
except (AttributeError, ValueError):
return None
# 组合所有 Mixin 的基类
class SchemaMixin(TimestampMixin, DisplayLabelMixin, FileFieldMixin):
"""
Schema 通用 Mixin
组合所有常用的字段解析方法
"""
pass
|