fastadmin 0.2.8__py3-none-any.whl → 0.2.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fastadmin/api/service.py CHANGED
@@ -53,7 +53,7 @@ def convert_id(id: str | int | UUID) -> int | UUID | None:
53
53
  if re.fullmatch(r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", id):
54
54
  return UUID(id)
55
55
 
56
- logger.error("Invalid id: %s", id)
56
+ logger.warning("Invalid id: %s", id)
57
57
  return None
58
58
 
59
59
 
@@ -101,6 +101,7 @@ class ApiService:
101
101
  ) -> str:
102
102
  model = settings.ADMIN_USER_MODEL
103
103
  admin_model = get_admin_model(model)
104
+
104
105
  if not admin_model:
105
106
  raise AdminApiException(401, detail=f"{model} model is not registered.")
106
107
 
@@ -334,8 +334,6 @@ class DjangoORMMixin:
334
334
 
335
335
  :return: A list of ids.
336
336
  """
337
- if not ids:
338
- return
339
337
  m2m_rel = getattr(obj, field)
340
338
  m2m_rel.set(ids)
341
339
 
@@ -3,7 +3,7 @@ from typing import Any
3
3
  from uuid import UUID
4
4
 
5
5
  from asgiref.sync import sync_to_async
6
- from pony.orm import commit, db_session, desc, flush, select
6
+ from pony.orm import commit, db_session, desc, flush
7
7
 
8
8
  from fastadmin.models.base import InlineModelAdmin, ModelAdmin
9
9
  from fastadmin.models.schemas import ModelFieldWidgetSchema, WidgetType
@@ -233,7 +233,7 @@ class PonyORMMixin:
233
233
  :return: A tuple of list of objects and total count.
234
234
  """
235
235
 
236
- qs = select(m for m in self.model_cls)
236
+ qs = getattr(self.model_cls, "select")(lambda m: m) # noqa: B009
237
237
  if filters:
238
238
  for field_with_condition, value in filters.items():
239
239
  field = field_with_condition[0]
@@ -256,14 +256,17 @@ class PonyORMMixin:
256
256
  case "contains":
257
257
  pony_condition = "in"
258
258
  case "icontains":
259
+ # TODO: support icontains here
259
260
  pony_condition = "in"
260
261
  filter_expr = f""""{value}" {pony_condition} m.{field}"""
261
262
  qs = qs.filter(filter_expr)
262
263
 
263
264
  if search and self.search_fields:
264
265
  ids = []
265
- for f in self.search_fields:
266
- qs_ids = qs.filter(lambda m: search.lower() in getattr(m, f).lower()) # noqa: B023
266
+ for search_field in self.search_fields:
267
+ # TODO: support icontains here
268
+ filter_expr = f""""{search}" in m.{search_field}"""
269
+ qs_ids = qs.filter(filter_expr)
267
270
  ids += [o.id for o in qs_ids]
268
271
  qs = qs.filter(lambda m: m.id in set(ids))
269
272
 
@@ -362,11 +365,12 @@ class PonyORMMixin:
362
365
  obj = next((i for i in self.model_cls.select(**{key_id: getattr(obj, key_id)})), None)
363
366
  if not obj:
364
367
  return
365
- rel_model_cls = getattr(self.model_cls, field).py_type
366
- rel_key_id = self.get_model_pk_name(rel_model_cls)
367
- rel_objs = list(rel_model_cls.select(lambda o: getattr(o, rel_key_id) in ids))
368
368
  obj.participants.clear()
369
- obj.participants.add(rel_objs)
369
+ if ids:
370
+ rel_model_cls = getattr(self.model_cls, field).py_type
371
+ rel_key_id = self.get_model_pk_name(rel_model_cls)
372
+ rel_objs = list(rel_model_cls.select(lambda o: getattr(o, rel_key_id) in ids))
373
+ obj.participants.add(rel_objs)
370
374
  flush()
371
375
  commit()
372
376
 
@@ -400,7 +400,8 @@ class SqlAlchemyMixin:
400
400
  obj_field_name: obj_id,
401
401
  }
402
402
  )
403
- await session.execute(orm_model_field.secondary.insert().values(values))
403
+ if values:
404
+ await session.execute(orm_model_field.secondary.insert().values(values))
404
405
  await session.commit()
405
406
 
406
407
  async def orm_save_upload_field(self, obj: Any, field: str, base64: str) -> None:
@@ -1,6 +1,10 @@
1
+ import functools
2
+ import operator
1
3
  from typing import Any
2
4
  from uuid import UUID
3
5
 
6
+ from tortoise.expressions import Q
7
+
4
8
  from fastadmin.models.base import InlineModelAdmin, ModelAdmin
5
9
  from fastadmin.models.schemas import ModelFieldWidgetSchema, WidgetType
6
10
  from fastadmin.settings import settings
@@ -244,11 +248,13 @@ class TortoiseMixin:
244
248
  qs = qs.filter(**{f"{field}__{condition}" if condition != "exact" else field: value})
245
249
 
246
250
  if search and self.search_fields:
247
- ids = []
248
- for f in self.search_fields:
249
- qs = qs.filter(**{f + "__icontains": search})
250
- ids += await qs.values_list(self.get_model_pk_name(self.model_cls), flat=True)
251
- qs = qs.filter(id__in=set(ids))
251
+ qs = qs.filter(
252
+ functools.reduce(
253
+ operator.or_,
254
+ (Q(**{f + "__icontains": search}) for f in self.search_fields),
255
+ Q(),
256
+ )
257
+ )
252
258
 
253
259
  if sort_by:
254
260
  qs = qs.order_by(sort_by)
@@ -323,8 +329,6 @@ class TortoiseMixin:
323
329
 
324
330
  :return: A list of ids.
325
331
  """
326
- if not ids:
327
- return
328
332
  m2m_rel = getattr(obj, field)
329
333
 
330
334
  await m2m_rel.clear()
@@ -335,7 +339,8 @@ class TortoiseMixin:
335
339
  setattr(remote_model_obj, self.get_model_pk_name(remote_model), rel_id)
336
340
  remote_model_obj._saved_in_db = True
337
341
  remote_model_objs.append(remote_model_obj)
338
- await m2m_rel.add(*remote_model_objs)
342
+ if remote_model_objs:
343
+ await m2m_rel.add(*remote_model_objs)
339
344
 
340
345
  async def orm_save_upload_field(self, obj: Any, field: str, base64: str) -> None:
341
346
  """This method is used to save upload field.