openedx-learning 0.29.1__py2.py3-none-any.whl → 0.30.0__py2.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.
@@ -2,4 +2,4 @@
2
2
  Open edX Learning ("Learning Core").
3
3
  """
4
4
 
5
- __version__ = "0.29.1"
5
+ __version__ = "0.30.0"
@@ -6,7 +6,7 @@ from __future__ import annotations
6
6
  import functools
7
7
 
8
8
  from django.contrib import admin
9
- from django.db.models import Count
9
+ from django.db.models import Count, F
10
10
  from django.utils.html import format_html
11
11
  from django.utils.safestring import SafeText
12
12
 
@@ -21,6 +21,7 @@ from .models import (
21
21
  EntityListRow,
22
22
  LearningPackage,
23
23
  PublishableEntity,
24
+ PublishableEntityVersion,
24
25
  PublishLog,
25
26
  PublishLogRecord,
26
27
  )
@@ -48,6 +49,7 @@ class PublishLogRecordTabularInline(admin.TabularInline):
48
49
  "title",
49
50
  "old_version_num",
50
51
  "new_version_num",
52
+ "dependencies_hash_digest",
51
53
  )
52
54
  readonly_fields = fields
53
55
 
@@ -89,28 +91,89 @@ class PublishLogAdmin(ReadOnlyModelAdmin):
89
91
  list_filter = ["learning_package"]
90
92
 
91
93
 
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
+
125
+ class PublishStatusFilter(admin.SimpleListFilter):
126
+ """
127
+ Custom filter for entities that have unpublished changes.
128
+ """
129
+ title = "publish status"
130
+ parameter_name = "publish_status"
131
+
132
+ def lookups(self, request, model_admin):
133
+ return [
134
+ ("unpublished_changes", "Has unpublished changes"),
135
+ ]
136
+
137
+ def queryset(self, request, queryset):
138
+ if self.value() == "unpublished_changes":
139
+ return (
140
+ queryset
141
+ .exclude(
142
+ published__version__isnull=True,
143
+ draft__version__isnull=True,
144
+ )
145
+ .exclude(
146
+ published__version=F("draft__version"),
147
+ published__dependencies_hash_digest=F("draft__dependencies_hash_digest")
148
+ )
149
+ )
150
+ return queryset
151
+
152
+
92
153
  @admin.register(PublishableEntity)
93
154
  class PublishableEntityAdmin(ReadOnlyModelAdmin):
94
155
  """
95
156
  Read-only admin view for Publishable Entities
96
157
  """
158
+ inlines = [PublishableEntityVersionTabularInline]
159
+
97
160
  list_display = [
98
161
  "key",
99
- "draft_version",
100
162
  "published_version",
163
+ "draft_version",
101
164
  "uuid",
102
165
  "learning_package",
103
166
  "created",
104
167
  "created_by",
105
168
  "can_stand_alone",
106
169
  ]
107
- list_filter = ["learning_package"]
170
+ list_filter = ["learning_package", PublishStatusFilter]
108
171
  search_fields = ["key", "uuid"]
109
172
 
110
173
  fields = [
111
174
  "key",
112
- "draft_version",
113
175
  "published_version",
176
+ "draft_version",
114
177
  "uuid",
115
178
  "learning_package",
116
179
  "created",
@@ -120,8 +183,8 @@ class PublishableEntityAdmin(ReadOnlyModelAdmin):
120
183
  ]
121
184
  readonly_fields = [
122
185
  "key",
123
- "draft_version",
124
186
  "published_version",
187
+ "draft_version",
125
188
  "uuid",
126
189
  "learning_package",
127
190
  "created",
@@ -130,21 +193,55 @@ class PublishableEntityAdmin(ReadOnlyModelAdmin):
130
193
  "can_stand_alone",
131
194
  ]
132
195
 
133
- def draft_version(self, entity: PublishableEntity):
134
- return entity.draft.version.version_num if entity.draft.version else None
135
-
136
- def published_version(self, entity: PublishableEntity):
137
- return entity.published.version.version_num if entity.published and entity.published.version else None
138
-
139
196
  def get_queryset(self, request):
140
197
  queryset = super().get_queryset(request)
141
198
  return queryset.select_related(
142
- "learning_package", "published__version",
199
+ "learning_package", "published__version", "draft__version", "created_by"
143
200
  )
144
201
 
145
202
  def see_also(self, entity):
146
203
  return one_to_one_related_model_html(entity)
147
204
 
205
+ def draft_version(self, entity: PublishableEntity):
206
+ """
207
+ Version num + dependency hash if applicable, e.g. "5" or "5 (825064c2)"
208
+
209
+ If the version info is different from the published version, we
210
+ italicize the text for emphasis.
211
+ """
212
+ if hasattr(entity, "draft") and entity.draft.version:
213
+ draft_log_record = entity.draft.draft_log_record
214
+ if draft_log_record and draft_log_record.dependencies_hash_digest:
215
+ version_str = (
216
+ f"{entity.draft.version.version_num} "
217
+ f"({draft_log_record.dependencies_hash_digest})"
218
+ )
219
+ else:
220
+ version_str = str(entity.draft.version.version_num)
221
+
222
+ if version_str == self.published_version(entity):
223
+ return version_str
224
+ else:
225
+ return format_html("<em>{}</em>", version_str)
226
+
227
+ return None
228
+
229
+ def published_version(self, entity: PublishableEntity):
230
+ """
231
+ Version num + dependency hash if applicable, e.g. "5" or "5 (825064c2)"
232
+ """
233
+ if hasattr(entity, "published") and entity.published.version:
234
+ publish_log_record = entity.published.publish_log_record
235
+ if publish_log_record.dependencies_hash_digest:
236
+ return (
237
+ f"{entity.published.version.version_num} "
238
+ f"({publish_log_record.dependencies_hash_digest})"
239
+ )
240
+ else:
241
+ return str(entity.published.version.version_num)
242
+
243
+ return None
244
+
148
245
 
149
246
  @admin.register(Published)
150
247
  class PublishedAdmin(ReadOnlyModelAdmin):
@@ -197,6 +294,7 @@ class DraftChangeLogRecordTabularInline(admin.TabularInline):
197
294
  "title",
198
295
  "old_version_num",
199
296
  "new_version_num",
297
+ "dependencies_hash_digest",
200
298
  )
201
299
  readonly_fields = fields
202
300