66import functools
77
88from django .contrib import admin
9- from django .db .models import Count
9+ from django .db .models import Count , F , Q
1010from django .utils .html import format_html
1111from django .utils .safestring import SafeText
1212
2121 EntityListRow ,
2222 LearningPackage ,
2323 PublishableEntity ,
24+ PublishableEntityVersion ,
25+ PublishableEntityVersionDependency ,
2426 PublishLog ,
2527 PublishLogRecord ,
2628)
@@ -89,28 +91,84 @@ class PublishLogAdmin(ReadOnlyModelAdmin):
8991 list_filter = ["learning_package" ]
9092
9193
94+ class PublishableEntityVersionTabularInline (admin .TabularInline ):
95+ """
96+ Tabular inline for a single Draft change.
97+ """
98+ model = PublishableEntityVersion
99+
100+ fields = (
101+ "version_num" ,
102+ "title" ,
103+ "created" ,
104+ "created_by" ,
105+ "dependencies_list" ,
106+ )
107+ readonly_fields = fields
108+
109+ def dependencies_list (self , version : PublishableEntityVersion ):
110+ identifiers = sorted (
111+ [str (dep .key ) for dep in version .dependencies .all ()]
112+ )
113+ return "\n " .join (identifiers )
114+
115+ def get_queryset (self , request ):
116+ queryset = super ().get_queryset (request )
117+ return (
118+ queryset
119+ .order_by ('-version_num' )
120+ .select_related ('created_by' , 'entity' )
121+ .prefetch_related ('dependencies' )
122+ )
123+
124+ class PublishStatusFilter (admin .SimpleListFilter ):
125+ title = "publish status"
126+ parameter_name = "publish_status"
127+
128+ def lookups (self , request , model_admin ):
129+ return [
130+ ("unpublished_changes" , "Has unpublished changes" ),
131+ ]
132+
133+ def queryset (self , request , queryset ):
134+ if self .value () == "unpublished_changes" :
135+ return (
136+ queryset
137+ .exclude (
138+ published__version__isnull = True ,
139+ draft__version__isnull = True ,
140+ )
141+ .exclude (
142+ published__version = F ("draft__version" ),
143+ published__dependencies_hash_digest = F ("draft__dependencies_hash_digest" )
144+ )
145+ )
146+
147+
92148@admin .register (PublishableEntity )
93149class PublishableEntityAdmin (ReadOnlyModelAdmin ):
94150 """
95151 Read-only admin view for Publishable Entities
96152 """
153+ inlines = [PublishableEntityVersionTabularInline ]
154+
97155 list_display = [
98156 "key" ,
99- "draft_version" ,
100157 "published_version" ,
158+ "draft_version" ,
101159 "uuid" ,
102160 "learning_package" ,
103161 "created" ,
104162 "created_by" ,
105163 "can_stand_alone" ,
106164 ]
107- list_filter = ["learning_package" ]
165+ list_filter = ["learning_package" , PublishStatusFilter ]
108166 search_fields = ["key" , "uuid" ]
109167
110168 fields = [
111169 "key" ,
112- "draft_version" ,
113170 "published_version" ,
171+ "draft_version" ,
114172 "uuid" ,
115173 "learning_package" ,
116174 "created" ,
@@ -120,8 +178,8 @@ class PublishableEntityAdmin(ReadOnlyModelAdmin):
120178 ]
121179 readonly_fields = [
122180 "key" ,
123- "draft_version" ,
124181 "published_version" ,
182+ "draft_version" ,
125183 "uuid" ,
126184 "learning_package" ,
127185 "created" ,
@@ -131,20 +189,54 @@ class PublishableEntityAdmin(ReadOnlyModelAdmin):
131189 ]
132190
133191 def draft_version (self , entity : PublishableEntity ):
134- return entity .draft .version .version_num if entity .draft .version else None
192+ from django .utils .html import format_html
193+
194+ if hasattr (entity , "draft" ) and entity .draft .version :
195+ if entity .draft .dependencies_hash_digest :
196+ version_str = (
197+ f"{ entity .draft .version .version_num } "
198+ f"({ entity .draft .dependencies_hash_digest } )"
199+ )
200+ else :
201+ version_str = str (entity .draft .version .version_num )
202+
203+ if version_str == self .published_version (entity ):
204+ return version_str
205+ else :
206+ return format_html ("<em>{}</em>" , version_str )
207+
208+ return None
135209
136210 def published_version (self , entity : PublishableEntity ):
137211 return entity .published .version .version_num if entity .published and entity .published .version else None
138212
139213 def get_queryset (self , request ):
140214 queryset = super ().get_queryset (request )
141215 return queryset .select_related (
142- "learning_package" , "published__version" ,
216+ "learning_package" , "published__version" , "draft__version" , "created_by"
143217 )
144218
145219 def see_also (self , entity ):
146220 return one_to_one_related_model_html (entity )
147221
222+ def published_version (self , entity ):
223+ if entity .published .version :
224+ return entity .published .version .version_num
225+ return None
226+
227+ def published_version (self , entity : PublishableEntity ):
228+ if hasattr (entity , "published" ) and entity .published .version :
229+ if entity .published .dependencies_hash_digest :
230+ return (
231+ f"{ entity .published .version .version_num } "
232+ f"({ entity .published .dependencies_hash_digest } )"
233+ )
234+ else :
235+ return str (entity .published .version .version_num )
236+
237+ return None
238+
239+
148240
149241@admin .register (Published )
150242class PublishedAdmin (ReadOnlyModelAdmin ):
0 commit comments