1212 Union ,
1313 cast ,
1414)
15+ from uuid import UUID
1516
1617from fastapi import APIRouter , Depends , Request , UploadFile
1718from fastapi .responses import JSONResponse , RedirectResponse , Response
3940class BulkDeleteRequest (BaseModel ):
4041 """Request model for bulk delete operations containing IDs to delete."""
4142
42- ids : List [int ]
43+ ids : List [Union [ int , str ] ]
4344
4445
4546class PasswordTransformer :
@@ -372,6 +373,11 @@ def __init__(
372373 self .model = model
373374 self .model_key = model .__name__
374375 self .router = APIRouter ()
376+ self .admin_model = admin_model
377+ self .admin_site = admin_site
378+ self .allowed_actions = allowed_actions
379+ self .event_integration = event_integration
380+ self .password_transformer = password_transformer
375381
376382 get_session : Callable [[], AsyncGenerator [AsyncSession , None ]]
377383 if self ._model_is_admin_model (model ):
@@ -388,12 +394,6 @@ def __init__(
388394 self .delete_schema = delete_schema
389395 self .select_schema = select_schema
390396
391- self .admin_model = admin_model
392- self .admin_site = admin_site
393- self .allowed_actions = allowed_actions
394- self .event_integration = event_integration
395- self .password_transformer = password_transformer
396-
397397 self .user_service = (
398398 self .admin_site .admin_user_service if self .admin_site else None
399399 )
@@ -432,17 +432,32 @@ def get_url_prefix(self) -> str:
432432 return ""
433433
434434 def _model_is_admin_model (self , model : Type [DeclarativeBase ]) -> bool :
435- """Check if the given model is one of the admin-specific models."""
436- admin_model_names = [
437- self .db_config .AdminUser .__name__ ,
438- self .db_config .AdminSession .__name__ ,
439- ]
440- if self .db_config .AdminEventLog :
441- admin_model_names .append (self .db_config .AdminEventLog .__name__ )
442- if self .db_config .AdminAuditLog :
443- admin_model_names .append (self .db_config .AdminAuditLog .__name__ )
444-
445- return model .__name__ in admin_model_names
435+ """Check if a model is considered an admin model."""
436+ return self .admin_model or self .model_key .lower () in {"adminuser" , "admin_user" }
437+
438+ def _convert_id_to_pk_type (
439+ self , id_value : Union [int , str ]
440+ ) -> Union [int , str , float ]:
441+ """Convert the ID value to the appropriate type based on the model's primary key type."""
442+ if id_value is None :
443+ return None
444+
445+ primary_key_info = self .db_config .get_primary_key_info (self .model )
446+ if not primary_key_info :
447+ return id_value
448+
449+ pk_type = primary_key_info .get ("type" )
450+
451+ if pk_type is int :
452+ return int (id_value ) if isinstance (id_value , str ) else id_value
453+ elif pk_type is str :
454+ return str (id_value )
455+ elif pk_type is float :
456+ return float (id_value ) if isinstance (id_value , str ) else id_value
457+ elif pk_type is UUID :
458+ return str (id_value )
459+ else :
460+ return str (id_value )
446461
447462 def setup_routes (self ) -> None :
448463 """
@@ -1063,12 +1078,14 @@ def get_model_update_page(self, template: str) -> EndpointCallable:
10631078
10641079 async def get_model_update_page_inner (
10651080 request : Request ,
1066- id : int ,
1081+ id : Union [ int , str ] ,
10671082 db : AsyncSession = Depends (self .session ),
10681083 ) -> Response :
10691084 """Show a form to update an existing record by `id`."""
1085+ converted_id = self ._convert_id_to_pk_type (id )
1086+
10701087 item = await self .crud .get (
1071- db = db , id = id , schema_to_select = self .select_schema
1088+ db = db , id = converted_id , schema_to_select = self .select_schema
10721089 )
10731090 if not item :
10741091 return JSONResponse (
@@ -1118,7 +1135,7 @@ async def form_update_endpoint_inner(
11181135 cast (Any , self .admin_site ).admin_authentication .get_current_user ()
11191136 ),
11201137 event_integration = Depends (lambda : self .event_integration ),
1121- id : Optional [int ] = None ,
1138+ id : Optional [Union [ int , str ] ] = None ,
11221139 ) -> Response :
11231140 """Handle POST form submission to update an existing record."""
11241141 assert self .admin_site is not None
@@ -1128,8 +1145,10 @@ async def form_update_endpoint_inner(
11281145 status_code = 422 , content = {"message" : "No id parameter provided" }
11291146 )
11301147
1148+ converted_id = self ._convert_id_to_pk_type (id )
1149+
11311150 item = await self .crud .get (
1132- db = db , id = id , schema_to_select = self .select_schema
1151+ db = db , id = converted_id , schema_to_select = self .select_schema
11331152 )
11341153 if not item :
11351154 return JSONResponse (
@@ -1187,29 +1206,33 @@ async def form_update_endpoint_inner(
11871206 AdminUserUpdateInternal (** transformed_data )
11881207 )
11891208 await self .crud .update (
1190- db = db , id = id , object = admin_update_schema
1209+ db = db , id = converted_id , object = admin_update_schema
11911210 )
11921211 else :
11931212 if self .update_internal_schema :
11941213 generic_update_schema = self .update_internal_schema (
11951214 ** transformed_data
11961215 )
11971216 await self .crud .update (
1198- db = db , id = id , object = generic_update_schema
1217+ db = db ,
1218+ id = converted_id ,
1219+ object = generic_update_schema ,
11991220 )
12001221 else :
12011222 dynamic_update_schema = type (
12021223 "InternalSchema" , (BaseModel ,), {}
12031224 )(** transformed_data )
12041225 await self .crud .update (
1205- db = db , id = id , object = dynamic_update_schema
1226+ db = db ,
1227+ id = converted_id ,
1228+ object = dynamic_update_schema ,
12061229 )
12071230
12081231 await db .commit ()
12091232 else :
12101233 update_schema_instance = self .update_schema (** update_data )
12111234 await self .crud .update (
1212- db = db , id = id , object = update_schema_instance
1235+ db = db , id = converted_id , object = update_schema_instance
12131236 )
12141237 await db .commit ()
12151238
0 commit comments