@@ -20,9 +20,7 @@ async def obj_to_dict(obj: Any, with_m2m: bool = True) -> dict:
2020 obj_dict = {k : v for k , v in obj .__dict__ .items () if not k .startswith ("_" )}
2121 if with_m2m :
2222 for field in obj .__class__ ._meta .m2m_fields :
23- m2m_rel = getattr (obj , field , None )
24- if m2m_rel is None :
25- continue
23+ m2m_rel = getattr (obj , field )
2624 remote_model = m2m_rel .remote_model
2725 remote_ids = await m2m_rel .all ().values_list (remote_model ._meta .pk_attr , flat = True )
2826 obj_dict [field ] = remote_ids
@@ -57,9 +55,7 @@ async def save_model(self, id: UUID | int | None, payload: dict) -> dict | None:
5755
5856 for key , values in payload .items ():
5957 if key in m2m_fields :
60- m2m_rel = getattr (obj , key , None )
61- if m2m_rel is None :
62- continue
58+ m2m_rel = getattr (obj , key )
6359 remote_model = m2m_rel .remote_model
6460 await m2m_rel .clear ()
6561 remote_model_objs = []
@@ -117,15 +113,17 @@ async def get_list(
117113 field = filter_condition .split ("__" , 1 )[0 ]
118114 if field not in fields :
119115 raise HTTPException (
120- status .HTTP_400_BAD_REQUEST , detail = f"Filter by { filter_condition } is not allowed"
116+ status .HTTP_422_UNPROCESSABLE_ENTITY , detail = f"Filter by { filter_condition } is not allowed"
121117 )
122118 qs = qs .filter (** {filter_condition : value })
123119
124120 if search :
125121 if self .search_fields :
126122 for field in self .search_fields :
127123 if field not in fields :
128- raise HTTPException (status .HTTP_400_BAD_REQUEST , detail = f"Search by { field } is not allowed" )
124+ raise HTTPException (
125+ status .HTTP_422_UNPROCESSABLE_ENTITY , detail = f"Search by { field } is not allowed"
126+ )
129127 ids = await asyncio .gather (
130128 * (qs .filter (** {f + "__icontains" : search }).values_list ("id" , flat = True ) for f in self .search_fields )
131129 )
@@ -134,12 +132,15 @@ async def get_list(
134132
135133 if sort_by :
136134 if sort_by .strip ("-" ) not in fields :
137- raise HTTPException (status .HTTP_400_BAD_REQUEST , detail = f"Sort by { sort_by } is not allowed" )
135+ raise HTTPException (status .HTTP_422_UNPROCESSABLE_ENTITY , detail = f"Sort by { sort_by } is not allowed" )
138136 qs = qs .order_by (sort_by )
139137 else :
140138 if self .ordering :
141- if self .ordering .strip ("-" ) not in fields :
142- raise HTTPException (status .HTTP_400_BAD_REQUEST , detail = f"Sort by { self .ordering } is not allowed" )
139+ for sort_by in self .ordering :
140+ if sort_by .strip ("-" ) not in fields :
141+ raise HTTPException (
142+ status .HTTP_422_UNPROCESSABLE_ENTITY , detail = f"Sort by { sort_by } is not allowed"
143+ )
143144 qs = qs .order_by (* self .ordering )
144145
145146 total = await qs .count ()
@@ -151,8 +152,10 @@ async def get_list(
151152 if self .list_select_related :
152153 for field in self .list_select_related :
153154 if field not in fields :
154- raise HTTPException (status .HTTP_400_BAD_REQUEST , detail = f"Select related by { field } is not allowed" )
155- qs = qs .select_related (* self .list_select_related )
155+ raise HTTPException (
156+ status .HTTP_422_UNPROCESSABLE_ENTITY , detail = f"Select related by { field } is not allowed"
157+ )
158+ qs = qs .select_related (* (f .replace ("_id" , "" ) for f in self .list_select_related ))
156159
157160 results = await asyncio .gather (* (obj_to_dict (obj , with_m2m = False ) for obj in await qs ))
158161
@@ -186,14 +189,7 @@ def get_model_fields(self) -> OrderedDict[str, dict]:
186189 parent_model_label = "id"
187190 if parent_admin_model :
188191 parent_model_id = parent_admin_model .model_cls ._meta .pk_attr
189- parent_model_label = parent_admin_model .model_cls ._meta .pk_attr
190- parent_fields = parent_admin_model .model_cls ._meta .fields_db_projection .keys ()
191- if "name" in parent_fields :
192- parent_model_label = "name"
193- elif "title" in parent_fields :
194- parent_model_label = "title"
195- elif "email" in parent_fields :
196- parent_model_label = "email"
192+ parent_model_label = parent_admin_model .repr_field or parent_model_id
197193
198194 form_hidden = (
199195 getattr (field , "_generated" , False )
@@ -231,7 +227,7 @@ def get_form_widget(self, field_name: str) -> tuple[WidgetType, dict]:
231227 fields = self .get_model_fields ()
232228 field = fields .get (field_name )
233229 if not field :
234- raise Exception ("Invalid field name %s" % field_name )
230+ raise ValueError ("Invalid field name %s" % field_name )
235231 widget_props = {
236232 "required" : field .get ("required" ) or False ,
237233 "disabled" : field_name in self .readonly_fields ,
0 commit comments