Skip to content

Commit 4d93e8b

Browse files
committed
Fix issue with modal inline dialogs. Fix issue with m2m multiple select.
1 parent 90d1670 commit 4d93e8b

8 files changed

Lines changed: 53 additions & 13 deletions

File tree

docs/build.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ def read_cls_docstring(cls):
3939

4040
def get_versions():
4141
return [
42+
{
43+
"version": "0.2.10",
44+
"changes": [
45+
"Fix issue empty m2m.",
46+
],
47+
},
4248
{
4349
"version": "0.2.9",
4450
"changes": [

docs/index.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

fastadmin/models/orms/django.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,6 @@ def orm_save_m2m_ids(self, obj: Any, field: str, ids: list[int | UUID]) -> None:
334334
335335
:return: A list of ids.
336336
"""
337-
if not ids:
338-
return
339337
m2m_rel = getattr(obj, field)
340338
m2m_rel.set(ids)
341339

fastadmin/models/orms/ponyorm.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,12 @@ def orm_save_m2m_ids(self, obj: Any, field: str, ids: list[int | UUID]) -> None:
362362
obj = next((i for i in self.model_cls.select(**{key_id: getattr(obj, key_id)})), None)
363363
if not obj:
364364
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))
368365
obj.participants.clear()
369-
obj.participants.add(rel_objs)
366+
if ids:
367+
rel_model_cls = getattr(self.model_cls, field).py_type
368+
rel_key_id = self.get_model_pk_name(rel_model_cls)
369+
rel_objs = list(rel_model_cls.select(lambda o: getattr(o, rel_key_id) in ids))
370+
obj.participants.add(rel_objs)
370371
flush()
371372
commit()
372373

fastadmin/models/orms/sqlalchemy.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ async def orm_save_m2m_ids(self, obj: Any, field: str, ids: list[int | UUID]) ->
400400
obj_field_name: obj_id,
401401
}
402402
)
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))
404405
await session.commit()
405406

406407
async def orm_save_upload_field(self, obj: Any, field: str, base64: str) -> None:

fastadmin/models/orms/tortoise.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,6 @@ async def orm_save_m2m_ids(self, obj: Any, field: str, ids: list[int | UUID]) ->
323323
324324
:return: A list of ids.
325325
"""
326-
if not ids:
327-
return
328326
m2m_rel = getattr(obj, field)
329327

330328
await m2m_rel.clear()
@@ -335,7 +333,8 @@ async def orm_save_m2m_ids(self, obj: Any, field: str, ids: list[int | UUID]) ->
335333
setattr(remote_model_obj, self.get_model_pk_name(remote_model), rel_id)
336334
remote_model_obj._saved_in_db = True
337335
remote_model_objs.append(remote_model_obj)
338-
await m2m_rel.add(*remote_model_objs)
336+
if remote_model_objs:
337+
await m2m_rel.add(*remote_model_objs)
339338

340339
async def orm_save_upload_field(self, obj: Any, field: str, base64: str) -> None:
341340
"""This method is used to save upload field.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "fastadmin"
3-
version = "0.2.9"
3+
version = "0.2.10"
44
description = "FastAdmin is an easy-to-use Admin Dashboard App for FastAPI/Flask/Django inspired by Django Admin."
55
authors = ["Seva D <[email protected]>"]
66
license = "MIT"

tests/api/test_change.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,41 @@ async def test_change(session_id, admin_models, event, client):
5252
assert r.status_code == 200, r.text
5353

5454

55+
async def test_change_empty_m2m(session_id, admin_models, event, client):
56+
assert session_id
57+
event_admin_model: ModelAdmin = admin_models[event.__class__]
58+
59+
r = await client.patch(
60+
f"/api/change/{event.get_model_name()}/{event.id}",
61+
json={
62+
"name": "new name",
63+
"participants": [],
64+
"rating": 10,
65+
"description": "test",
66+
"event_type": "PRIVATE",
67+
"is_active": True,
68+
"start_time": datetime.datetime.now(tz=datetime.UTC).isoformat(),
69+
"date": datetime.datetime.now(tz=datetime.UTC).isoformat(),
70+
"latitude": 0.2,
71+
"longitude": 0.4,
72+
# TODO: bug with Decimal
73+
# "price": "20.3",
74+
"json": {"test": "test"},
75+
},
76+
)
77+
78+
assert r.status_code == 200, r.text
79+
80+
updated_event = await event_admin_model.get_obj(event.id)
81+
item = r.json()
82+
assert item["id"] == updated_event["id"]
83+
assert item["name"] == updated_event["name"]
84+
assert item["tournament"] == updated_event["tournament"]
85+
assert datetime.datetime.fromisoformat(item["created_at"]) == updated_event["created_at"]
86+
assert datetime.datetime.fromisoformat(item["updated_at"]) == updated_event["updated_at"]
87+
assert item["participants"] == []
88+
89+
5590
async def test_change_405(session_id, event, client):
5691
assert session_id
5792
r = await client.get(

0 commit comments

Comments
 (0)