1414 from fastapi_jsonapi .views .list_view import ListViewBase
1515 from fastapi_jsonapi .views .view_base import ViewBase
1616
17+ LocalIdsType = Dict [str , Dict [str , str ]]
18+
1719
1820@dataclass
1921class OperationBase :
@@ -62,6 +64,55 @@ async def get_data_layer(self) -> BaseDataLayer:
6264 async def handle (self , dl : BaseDataLayer ):
6365 raise NotImplementedError
6466
67+ @classmethod
68+ def upd_one_relationship_with_local_id (cls , relationship_info : dict , local_ids : LocalIdsType ):
69+ """
70+ TODO: refactor
71+
72+ :param relationship_info:
73+ :param local_ids:
74+ :return:
75+ """
76+ missing = object ()
77+ lid = relationship_info .get ("lid" , missing )
78+ if lid is missing :
79+ return
80+
81+ resource_type = relationship_info ["type" ]
82+ if resource_type not in local_ids :
83+ msg = (
84+ f"Resource { resource_type } not found in previous operations,"
85+ f" no lid { lid } defined yet, cannot create { relationship_info } "
86+ )
87+ raise ValueError (
88+ msg ,
89+ )
90+
91+ lids_for_resource = local_ids [resource_type ]
92+ if lid not in lids_for_resource :
93+ msg = (
94+ f"lid { lid } for { resource_type } not found in previous operations,"
95+ f" cannot process { relationship_info } "
96+ )
97+ raise ValueError (msg )
98+
99+ relationship_info .pop ("lid" )
100+ relationship_info ["id" ] = lids_for_resource [lid ]
101+
102+ def update_relationships_with_lid (self , local_ids : LocalIdsType ):
103+ if not (self .data and self .data .relationships ):
104+ return
105+ for relationship_name , relationship_value in self .data .relationships .items ():
106+ relationship_data = relationship_value ["data" ]
107+ if isinstance (relationship_data , list ):
108+ for data in relationship_data :
109+ self .upd_one_relationship_with_local_id (data , local_ids = local_ids )
110+ elif isinstance (relationship_data , dict ):
111+ self .upd_one_relationship_with_local_id (relationship_data , local_ids = local_ids )
112+ else :
113+ msg = "unexpected relationship data"
114+ raise ValueError (msg )
115+
65116
66117class ListOperationBase (OperationBase ):
67118 view : ListViewBase
@@ -83,6 +134,10 @@ async def handle(self, dl: BaseDataLayer):
83134
84135class OperationUpdate (DetailOperationBase ):
85136 async def handle (self , dl : BaseDataLayer ):
137+ if self .data is None :
138+ # TODO: clear to-one relationships
139+ pass
140+ # TODO: handle relationship update requests (relationship resources)
86141 data_in = self .jsonapi .schema_in_patch (data = self .data )
87142 obj_id = self .ref and self .ref .id or self .data and self .data .id
88143 response = await self .view .process_update_object (
0 commit comments