@@ -26,116 +26,134 @@ def pairwise(iterable):
26
26
C = layout .grid .Col
27
27
28
28
29
- def history_tab ():
30
- """
31
- new_record, old_record = p.history.all()
32
- delta = new_record.diff_against(old_record)
33
- for change in delta.changes:
34
- print("{} changed from {} to {}".format(change.field, change.old, change.new))
35
- """
29
+ def changes (c ):
30
+ if c ["row" ][0 ] is not None and c ["row" ][1 ] is not None :
31
+ return list (c ["row" ][0 ].diff_against (c ["row" ][1 ]).changes )
32
+ return ()
33
+
34
+
35
+ def haschanges (a , b ):
36
+ return a is not None and b is not None and len (a .diff_against (b ).changes ) > 0
37
+
38
+
39
+ def fieldname (c , model ):
40
+ try :
41
+ return model ._meta .get_field (c ["change" ].field ).verbose_name
42
+ except FieldDoesNotExist :
43
+ return c ["change" ].field .replace ("_" , " " ).capitalize ()
36
44
37
- def changes (c ):
38
- if c ["row" ][1 ] is not None :
39
- return list (c ["row" ][0 ].diff_against (c ["row" ][1 ]).changes )
40
- return ()
41
45
42
- def haschanges (a , b ):
43
- return b is not None and len (a .diff_against (b ).changes ) > 0
46
+ def newfieldvalue (c , model ):
47
+ try :
48
+ field = model ._meta .get_field (c ["change" ].field )
49
+ if isinstance (field , RelatedField ):
50
+ try :
51
+ return field .related_model .objects .get (id = int (c ["change" ].new ))
52
+ except field .related_model .DoesNotExist :
53
+ return hg .SPAN (_ ("<Value has been deleted>" ), style = "color: red" )
54
+ except FieldDoesNotExist :
55
+ pass
56
+ return c ["change" ].new
44
57
58
+
59
+ def oldfieldvalue (c , model ):
60
+ try :
61
+ field = model ._meta .get_field (c ["change" ].field )
62
+ if isinstance (field , RelatedField ):
63
+ ret = field .related_model .objects .filter (id = int (c ["change" ].old )).first ()
64
+ return ret or hg .SPAN (_ ("<Value has been deleted>" ), style = "color: red" )
65
+ except FieldDoesNotExist :
66
+ pass
67
+ return c ["change" ].old
68
+
69
+
70
+ def diff_table (model , historylist , showObjectLabel = None ):
45
71
def historyentries (c ):
46
72
return (
47
73
(i , j )
48
- for i , j in pairwise (chain (c [ "object" ]. history . all ( ), [None ]))
74
+ for i , j in pairwise (chain (historylist ( c ), [None ]))
49
75
if haschanges (i , j )
50
76
)
51
77
52
- def fieldname (c ):
53
- try :
54
- return c ["object" ]._meta .get_field (c ["change" ].field ).verbose_name
55
- except FieldDoesNotExist :
56
- return c ["change" ].field .replace ("_" , " " ).capitalize ()
57
-
58
- def newfieldvalue (c ):
59
- try :
60
- field = c ["object" ]._meta .get_field (c ["change" ].field )
61
- if isinstance (field , RelatedField ):
62
- try :
63
- return field .related_model .objects .get (id = int (c ["change" ].new ))
64
- except field .related_model .DoesNotExist :
65
- return hg .SPAN (_ ("<Value has been deleted>" ), style = "color: red" )
66
- except FieldDoesNotExist :
67
- pass
68
- return c ["change" ].new
69
-
70
- def oldfieldvalue (c ):
71
- try :
72
- field = c ["object" ]._meta .get_field (c ["change" ].field )
73
- if isinstance (field , RelatedField ):
74
- ret = field .related_model .objects .filter (
75
- id = int (c ["change" ].old )
76
- ).first ()
77
- return ret or hg .SPAN (_ ("<Value has been deleted>" ), style = "color: red" )
78
- except FieldDoesNotExist :
79
- pass
80
- return c ["change" ].old
78
+ return layout .components .datatable .DataTable (
79
+ row_iterator = hg .F (historyentries ),
80
+ columns = [
81
+ layout .components .datatable .DataTableColumn (
82
+ _ ("Date" ),
83
+ layout .localize (layout .localtime (hg .C ("row" )[0 ].history_date ).date ()),
84
+ ),
85
+ layout .components .datatable .DataTableColumn (
86
+ _ ("Time" ),
87
+ layout .localize (layout .localtime (hg .C ("row" )[0 ].history_date ).time ()),
88
+ ),
89
+ layout .components .datatable .DataTableColumn (
90
+ _ ("User" ),
91
+ hg .C ("row" )[0 ].history_user ,
92
+ ),
93
+ * (
94
+ [
95
+ layout .components .datatable .DataTableColumn (
96
+ _ ("Object" ),
97
+ hg .F (lambda c : showObjectLabel (c ["row" ][0 ].instance )),
98
+ )
99
+ ]
100
+ if showObjectLabel is not None
101
+ else []
102
+ ),
103
+ layout .components .datatable .DataTableColumn (
104
+ _ ("Changes" ),
105
+ hg .UL (
106
+ hg .Iterator (
107
+ hg .F (changes ),
108
+ "change" ,
109
+ hg .LI (
110
+ hg .SPAN (
111
+ hg .F (lambda c : fieldname (c , model (c ))),
112
+ style = "font-weight: 600" ,
113
+ ),
114
+ ": " ,
115
+ hg .SPAN (
116
+ hg .If (
117
+ hg .C ("change" ).old ,
118
+ hg .F (lambda c : oldfieldvalue (c , model (c ))),
119
+ settings .HTML_NONE ,
120
+ ),
121
+ style = "text-decoration: line-through;" ,
122
+ ),
123
+ " -> " ,
124
+ hg .SPAN (
125
+ hg .If (
126
+ hg .C ("change" ).new ,
127
+ hg .F (lambda c : newfieldvalue (c , model (c ))),
128
+ settings .HTML_NONE ,
129
+ )
130
+ ),
131
+ ),
132
+ ),
133
+ ),
134
+ ),
135
+ ],
136
+ )
137
+
138
+
139
+ def history_tab ():
140
+ """
141
+ new_record, old_record = p.history.all()
142
+ delta = new_record.diff_against(old_record)
143
+ for change in delta.changes:
144
+ print("{} changed from {} to {}".format(change.field, change.old, change.new))
145
+ """
146
+
147
+ def historyentries (c ):
148
+ return c ["object" ].history .all ()
81
149
82
150
return layout .tabs .Tab (
83
151
_ ("History" ),
84
152
utils .grid_inside_tab (
85
153
R (
86
154
utils .tiling_col (
87
- layout .components .datatable .DataTable (
88
- row_iterator = hg .F (historyentries ),
89
- columns = [
90
- layout .components .datatable .DataTableColumn (
91
- _ ("Date" ),
92
- layout .localize (
93
- layout .localtime (hg .C ("row" )[0 ].history_date ).date ()
94
- ),
95
- ),
96
- layout .components .datatable .DataTableColumn (
97
- _ ("Time" ),
98
- layout .localize (
99
- layout .localtime (hg .C ("row" )[0 ].history_date ).time ()
100
- ),
101
- ),
102
- layout .components .datatable .DataTableColumn (
103
- _ ("User" ),
104
- hg .C ("row" )[0 ].history_user ,
105
- ),
106
- layout .components .datatable .DataTableColumn (
107
- _ ("Changes" ),
108
- hg .UL (
109
- hg .Iterator (
110
- hg .F (changes ),
111
- "change" ,
112
- hg .LI (
113
- hg .SPAN (
114
- hg .F (fieldname ),
115
- style = "font-weight: 600" ,
116
- ),
117
- ": " ,
118
- hg .SPAN (
119
- hg .If (
120
- hg .C ("change" ).old ,
121
- hg .F (oldfieldvalue ),
122
- settings .HTML_NONE ,
123
- ),
124
- style = "text-decoration: line-through;" ,
125
- ),
126
- " -> " ,
127
- hg .SPAN (
128
- hg .If (
129
- hg .C ("change" ).new ,
130
- hg .F (newfieldvalue ),
131
- settings .HTML_NONE ,
132
- )
133
- ),
134
- ),
135
- ),
136
- ),
137
- ),
138
- ],
155
+ diff_table (
156
+ lambda c : type (c ["object" ]), historyentries
139
157
).with_toolbar (_ ("Changes" ))
140
158
)
141
159
),
0 commit comments