from typing import Union, Any from pydantic import BaseModel, Field from bson.objectid import ObjectId class MdbObjectId(ObjectId): @classmethod def __get_validators__(cls): yield cls.validate @classmethod def validate(cls, v): if not isinstance(v, ObjectId): raise TypeError('ObjectId required') return v class GBaseModel(BaseModel): """ 字段名与保护变量命名冲突,将 _ 前缀变为后缀,读出再还原 """ id_: MdbObjectId = Field(..., title="平台") platform_: str = Field(None, title="平台") channel_name_: str = Field(None, title="channel") owner_name_: str = Field(None, title="owner") channel_uid_: str = Field(None, title="channel_uid") device_id_: str = Field(None, title='device_id') district_server_id_: int = Field(None, title="区服id") game_role_id_: str = Field(None, title="角色id") event_time_: int = Field(..., title="事件时间") role_create_time: int = Field(None, title="角色创建时间") role_level: int = Field(None, title="角色等级") role_vip: int = Field(None, title="角色vip等级") def __init__(self, **data: Any): if isinstance(data.get('_id'), str) and len(data['_id']) == 24: data['_id'] = ObjectId(data['_id']) new_data = {} for k, v in data.items(): # type:str,Any if k.startswith('_'): new_k = k[1:] + k[0] new_data[new_k] = v else: new_data[k] = v super().__init__(**new_data) def dict( self, *, include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None, by_alias: bool = False, skip_defaults: bool = None, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, ) -> 'DictStrAny': data = super().dict() new_data = {} for k, v in data.items(): # type:str,Any if k.endswith('_'): new_k = k[-1] + k[:-1] new_data[new_k] = v else: new_data[k] = v return new_data class Config: arbitrary_types_allowed = True @classmethod def get_fields(cls): fields = [] for k in cls.__fields__: if k.endswith('_'): fields.append(k[-1] + k[:-1]) else: fields.append(k) return fields if __name__ == '__main__': obj = GBaseModel(_id="5fd0f4812de17aeba6c1a374", role_level='2', aaa=123, _platform=13566) print(obj.dict()) print(obj.role_level)