Coverage for src/lexigram/admin/resources/mixins/has_infolist.py: 100%

17 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-21 14:56 +0800

1"""HasInfolist mixin for resources with read-only detail entries.""" 

2 

3from __future__ import annotations 

4 

5from collections.abc import Mapping 

6from typing import Any 

7 

8from lexigram.ui import InfolistEntry 

9 

10 

11class HasInfolist: 

12 """Build ``InfolistEntry`` values for a record on resource detail pages. 

13 

14 Uses the resource's declarative ``fields`` when set; otherwise 

15 derives entries from the resource ``model`` via 

16 ``FormSchemaGenerator``. Fields opt out via ``visible_in_view``. 

17 """ 

18 

19 def infolist(self, record: Mapping[str, Any]) -> list[InfolistEntry]: 

20 """Build infolist entries for a record. 

21 

22 Args: 

23 record: Flat record mapping (``model_dump()`` shape). 

24 

25 Returns: 

26 Entries for the fields visible in the detail view. 

27 """ 

28 return [ 

29 field.render_infolist_entry(record[field.name]) 

30 for field in self._infolist_fields() 

31 if getattr(field, "visible_in_view", True) and field.name in record 

32 ] 

33 

34 def _infolist_fields(self) -> list[Any]: 

35 fields = getattr(self, "fields", None) 

36 if fields: 

37 return list(fields) 

38 model = getattr(self, "model", None) 

39 if model is None: 

40 return [] 

41 from lexigram.admin.forms.components import FormSchemaGenerator 

42 

43 return list(FormSchemaGenerator().from_pydantic(model).fields) 

44 

45 

46__all__ = ["HasInfolist"]