@@ -30,7 +30,7 @@ class User(BubbleModel, typename="user"):
3030from bubble_data_api_client .client .raw_client import AdditionalSortField , RawClient
3131from bubble_data_api_client .constraints import Constraint , ConstraintType , constraint
3232from bubble_data_api_client .exceptions import BubbleAPIError , UnknownFieldError
33- from bubble_data_api_client .types import BubbleField , OnMultiple
33+ from bubble_data_api_client .types import BUILTIN_FIELDS , BubbleField , OnMultiple
3434
3535
3636def _get_client () -> RawClient :
@@ -69,18 +69,17 @@ def __init_subclass__(cls, *, typename: str, **kwargs: typing.Any) -> None:
6969 cls ._typename = typename
7070
7171 @classmethod
72- def _resolve_aliases (cls , data : dict [str , typing .Any ]) -> dict [str , typing .Any ]:
73- """Translate ORM field names to their aliases for API requests."""
74- resolved : dict [str , typing .Any ] = {}
75- for field_name , value in data .items ():
76- field_info = cls .model_fields .get (field_name )
77- if field_info is None :
72+ def _serialize_for_api (cls , data : dict [str , typing .Any ]) -> dict [str , typing .Any ]:
73+ """Serialize field data for API requests with aliasing and JSON conversion."""
74+ for field_name in data :
75+ if field_name not in cls .model_fields :
7876 raise UnknownFieldError (field_name )
79- if field_info .alias :
80- resolved [field_info .alias ] = value
81- else :
82- resolved [field_name ] = value
83- return resolved
77+ partial = cls .model_construct (** data )
78+ return partial .model_dump (
79+ mode = "json" ,
80+ include = set (data .keys ()),
81+ by_alias = True ,
82+ )
8483
8584 @classmethod
8685 async def create (cls , ** data : typing .Any ) -> typing .Self :
@@ -92,7 +91,7 @@ async def create(cls, **data: typing.Any) -> typing.Self:
9291 Returns:
9392 A new model instance with the assigned Bubble UID.
9493 """
95- aliased_data = cls ._resolve_aliases (data )
94+ aliased_data = cls ._serialize_for_api (data )
9695 async with _get_client () as client :
9796 response = await client .create (cls ._typename , aliased_data )
9897 uid = response .json ()["id" ]
@@ -129,15 +128,16 @@ async def save(self) -> None:
129128 async with _get_client () as client :
130129 # exclude uid and server-managed fields
131130 data = self .model_dump (
132- exclude = {"uid" , "created_date" , "modified_date" , "slug" },
131+ mode = "json" ,
132+ exclude = BUILTIN_FIELDS ,
133133 by_alias = True ,
134134 )
135135 await client .update (self ._typename , self .uid , data )
136136
137137 @classmethod
138138 async def update (cls , uid : str , ** data : typing .Any ) -> None :
139139 """Update specific fields on a thing by its unique ID."""
140- aliased_data = cls ._resolve_aliases (data )
140+ aliased_data = cls ._serialize_for_api (data )
141141 async with _get_client () as client :
142142 await client .update (cls ._typename , uid , aliased_data )
143143
@@ -284,9 +284,9 @@ async def create_or_update(
284284 on_multiple : OnMultiple ,
285285 ) -> tuple [typing .Self , bool ]:
286286 """Create a thing if it doesn't exist, or update if it does."""
287- aliased_match = cls ._resolve_aliases (match )
288- aliased_create_data = cls ._resolve_aliases (create_data ) if create_data else None
289- aliased_update_data = cls ._resolve_aliases (update_data ) if update_data else None
287+ aliased_match = cls ._serialize_for_api (match )
288+ aliased_create_data = cls ._serialize_for_api (create_data ) if create_data else None
289+ aliased_update_data = cls ._serialize_for_api (update_data ) if update_data else None
290290 async with _get_client () as client :
291291 result = await client .create_or_update (
292292 typename = cls ._typename ,
0 commit comments