Files
ToDoList/api/app/schemas/task.py
祀梦 2979197b1c release: Elysia ToDo v1.0.0
鍏ㄦ爤涓汉淇℃伅绠$悊搴旂敤锛岄泦鎴愬緟鍔炰换鍔°€佷範鎯墦鍗°€佺邯蹇垫棩鎻愰啋銆佽祫浜ф€昏鍔熻兘銆

Made-with: Cursor
2026-03-14 22:21:26 +08:00

86 lines
2.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from pydantic import BaseModel, Field, field_validator
from datetime import datetime
from typing import Optional, List
from app.schemas.category import CategoryResponse
from app.schemas.tag import TagResponse
def parse_datetime(value):
"""解析日期时间字符串"""
if value is None or value == '':
return None
if isinstance(value, datetime):
return value
# 尝试多种格式
formats = [
'%Y-%m-%dT%H:%M:%S',
'%Y-%m-%d %H:%M:%S',
'%Y-%m-%dT%H:%M:%S.%f',
]
for fmt in formats:
try:
return datetime.strptime(value, fmt)
except ValueError:
continue
# 最后尝试 ISO 格式
return datetime.fromisoformat(value.replace('Z', '+00:00'))
class TaskBase(BaseModel):
"""任务基础模型"""
title: str = Field(..., max_length=200)
description: Optional[str] = None
priority: str = Field(default="q4", pattern="^(q1|q2|q3|q4)$")
due_date: Optional[datetime] = None
category_id: Optional[int] = None
@field_validator('due_date', mode='before')
@classmethod
def parse_due_date(cls, v):
return parse_datetime(v)
class TaskCreate(TaskBase):
"""创建任务请求模型"""
tag_ids: Optional[List[int]] = []
class TaskUpdate(BaseModel):
"""更新任务请求模型
通过 exclude_unset=True 区分"前端没传""前端传了 null"
- 前端没传某个字段 -> model_dump 结果中不包含该 key -> 不修改
- 前端传了 null -> model_dump 结果中包含 key: None -> 视为"清空"
"""
title: Optional[str] = Field(None, max_length=200)
description: Optional[str] = None
priority: Optional[str] = Field(None, pattern="^(q1|q2|q3|q4)$")
due_date: Optional[datetime] = None
is_completed: Optional[bool] = None
category_id: Optional[int] = None
tag_ids: Optional[List[int]] = None
@field_validator('due_date', mode='before')
@classmethod
def parse_due_date(cls, v):
return parse_datetime(v)
@property
def clearable_fields(self) -> set:
"""允许被显式清空(设为 None的字段集合"""
return {'description', 'due_date', 'category_id'}
class TaskResponse(TaskBase):
"""任务响应模型"""
id: int
is_completed: bool
created_at: datetime
updated_at: datetime
category: Optional[CategoryResponse] = None
tags: List[TagResponse] = []
class Config:
from_attributes = True