from typing import Literal from pydantic import BaseModel, ConfigDict, Field, model_validator class PlaceSearchConfig(BaseModel): model_config = ConfigDict(extra="forbid", str_strip_whitespace=True) enabled: bool = False provider: Literal["tianditu"] = "tianditu" admin_code: str = Field(pattern=r"^(?:156)?[0-9]{6}$") region: str = Field(min_length=1, max_length=100) class ProjectMapConfig(BaseModel): # Preserve existing map options such as legend when editing search settings. model_config = ConfigDict(extra="allow") place_search: PlaceSearchConfig | None = None class ProjectMapConfigUpdate(BaseModel): map_config: ProjectMapConfig | None = None @model_validator(mode="after") def reject_null_map_config(self): if "map_config" in self.model_fields_set and self.map_config is None: raise ValueError("map_config must be an object") return self