Coverage for src/mesh/admin.py: 90%
103 statements
« prev ^ index » next coverage.py v7.7.0, created at 2025-04-28 07:45 +0000
« prev ^ index » next coverage.py v7.7.0, created at 2025-04-28 07:45 +0000
1from django.contrib import admin
2from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
3from django.forms import BaseForm
4from django.http import HttpRequest
5from django.utils.translation import gettext_lazy as _
7from .models.base_models import BaseChangeTrackingModel
8from .models.editorial_models import (
9 EditorialDecision,
10 EditorialDecisionFile,
11 EditorSectionRight,
12 EditorSubmissionRight,
13)
14from .models.file_models import BaseFileWrapperModel
15from .models.journal_models import JournalSection
16from .models.review_models import Review, ReviewAdditionalFile
17from .models.submission_models import (
18 Submission,
19 SubmissionAdditionalFile,
20 SubmissionAuthor,
21 SubmissionLog,
22 SubmissionMainFile,
23 SubmissionVersion,
24)
25from .models.user_models import SuggestedReviewer, Suggestion, User, UserToken
28def get_file_wrapper_inline(
29 model_class: type[BaseFileWrapperModel],
30 name_plural: str = "Files",
31 extra_fields: list[str] = [],
32 read_only_fields: list[str] = [],
33) -> type[admin.TabularInline]:
34 """
35 Returns a `TalubarInline` to display related `BaseFileWrapperModel` instances.
36 """
38 class FileWrapperInlineAdmin(admin.TabularInline):
39 model = model_class
40 extra = 0
41 verbose_name_plural = name_plural
42 fields = ["file", "name", *extra_fields]
43 readonly_fields = read_only_fields
45 return FileWrapperInlineAdmin
48class BaseUserChangeTrackingAdmin(admin.ModelAdmin):
49 """
50 Base admin model for models inheriting from BaseChangeTrackingModel.
51 Attach the request to the object to be saved.
52 """
54 readonly_fields: list[str] = [
55 "date_created",
56 "created_by",
57 "date_last_modified",
58 "last_modified_by",
59 ]
61 def save_model(
62 self,
63 request: HttpRequest,
64 obj: BaseChangeTrackingModel,
65 form: BaseForm,
66 change: bool,
67 ) -> None:
68 obj._user = request.user # type:ignore
69 # change = whether the object is being created or updated
70 if change and not form.has_changed():
71 obj.do_not_update = True
73 super().save_model(request, obj, form, change)
76class UserTokenInline(admin.StackedInline):
77 model = UserToken
78 fk_name = "user"
79 can_delete = False
80 fields = ["key", "date_refreshed", "date_created"]
81 readonly_fields = ["date_created"]
84@admin.register(User)
85class UserAdmin(DjangoUserAdmin):
86 """Define admin model for our custom User model having no email field."""
88 inlines = (UserTokenInline,)
89 fieldsets = (
90 (None, {"fields": ("email", "password")}),
91 (_("Personal info"), {"fields": ("first_name", "last_name")}),
92 (_("For staff"), {"fields": ["current_role", "journal_manager"]}),
93 (
94 _("Permissions"),
95 {
96 "fields": (
97 "is_active",
98 "is_staff",
99 "is_superuser",
100 "groups",
101 "user_permissions",
102 )
103 },
104 ),
105 (_("Important dates"), {"fields": ("last_login", "date_joined")}),
106 )
107 add_fieldsets = (
108 (
109 None,
110 {
111 "classes": ("wide",),
112 "fields": (
113 "email",
114 "password1",
115 "password2",
116 "first_name",
117 "last_name",
118 ),
119 },
120 ),
121 )
122 list_display = (
123 "email",
124 "first_name",
125 "last_name",
126 "current_role",
127 "is_staff",
128 "is_superuser",
129 "journal_manager",
130 )
131 search_fields = ("email", "first_name", "last_name")
132 ordering = ("email",)
133 readonly_fields = ["current_role", "last_login", "date_joined"]
136@admin.register(SubmissionLog)
137class ModelLogAdmin(BaseUserChangeTrackingAdmin):
138 list_display = [field.name for field in SubmissionLog._meta.get_fields()]
141@admin.register(JournalSection)
142class JournalSectionAdmin(BaseUserChangeTrackingAdmin):
143 fieldsets = (
144 (None, {"fields": ["name", "parent"]}),
145 (_("Object metadata"), {"fields": ["date_created", "created_by"]}),
146 )
147 list_display = ["name", "parent", "date_created", "created_by"]
150class EditorSubmissionRightInline(admin.TabularInline):
151 extra = 0
152 verbose_name_plural = _("Assigned Editors")
153 model = EditorSubmissionRight
156@admin.register(Submission)
157class SubmissionAdmin(BaseUserChangeTrackingAdmin):
158 inlines = (EditorSubmissionRightInline,)
159 fieldsets = (
160 (
161 _("Metadata"),
162 {"fields": ["created_by", "journal_section", "state", "date_created"]},
163 ),
164 (_("Submission data"), {"fields": ["name", "abstract"]}),
165 )
166 readonly_fields = ["name", "abstract"]
167 list_display = ["created_by", "date_created", "journal_section", "name", "state"]
169 def get_readonly_fields(self, request: HttpRequest, obj) -> set[str]:
170 return set(list(BaseUserChangeTrackingAdmin.readonly_fields) + list(self.readonly_fields))
173@admin.register(SubmissionVersion)
174class SubmissionVersionAdmin(BaseUserChangeTrackingAdmin):
175 inlines = (
176 get_file_wrapper_inline(SubmissionMainFile),
177 get_file_wrapper_inline(SubmissionAdditionalFile),
178 )
179 fieldsets = [
180 (
181 _("Submission version"),
182 {"fields": ["submission", "number", "submitted", "date_submitted"]},
183 )
184 ]
185 readonly_fields = ["submission", "number", "submitted", "date_submitted"]
186 list_display = [
187 "submission",
188 "number",
189 "date_created",
190 "submitted",
191 "date_submitted",
192 ]
194 def get_readonly_fields(self, request: HttpRequest, obj) -> set[str]:
195 return set(list(BaseUserChangeTrackingAdmin.readonly_fields) + list(self.readonly_fields))
198@admin.register(SubmissionAuthor)
199class SubmissionAuthorAdmin(BaseUserChangeTrackingAdmin):
200 fieldsets = [
201 (
202 None,
203 {
204 "fields": [
205 "first_name",
206 "last_name",
207 "email",
208 "corresponding",
209 "date_created",
210 "created_by",
211 ]
212 },
213 )
214 ]
215 list_display = [
216 "first_name",
217 "last_name",
218 "email",
219 "corresponding",
220 "date_created",
221 "created_by",
222 ]
225@admin.register(EditorSectionRight)
226class EditorSectionRightAdmin(BaseUserChangeTrackingAdmin):
227 fieldsets = [(None, {"fields": ["user", "journal_section", "date_created", "created_by"]})]
228 list_display = ["user", "journal_section", "date_created", "created_by"]
231@admin.register(EditorSubmissionRight)
232class EditorSubmissionRightAdmin(BaseUserChangeTrackingAdmin):
233 fieldsets = [(None, {"fields": ["user", "submission", "date_created", "created_by"]})]
234 list_display = ["user", "submission", "date_created", "created_by"]
237@admin.register(Review)
238class ReviewAdmin(BaseUserChangeTrackingAdmin):
239 inlines = (get_file_wrapper_inline(ReviewAdditionalFile, extra_fields=["author_access"]),)
240 fieldsets = [
241 (
242 None,
243 {
244 "fields": [
245 "version",
246 "reviewer",
247 "state",
248 "date_response_due",
249 "date_review_due",
250 "request_email",
251 "accepted",
252 "date_accepted",
253 "accept_comment",
254 "recommendation",
255 "comment",
256 "date_created",
257 "created_by",
258 ]
259 },
260 )
261 ]
262 list_display = [
263 "reviewer",
264 "date_response_due",
265 "accepted",
266 "date_review_due",
267 "recommendation",
268 "date_created",
269 "created_by",
270 ]
272 readonly_fields = ["version", "accepted", "date_accepted"]
274 def get_readonly_fields(self, request: HttpRequest, obj) -> set[str]:
275 return set(list(BaseUserChangeTrackingAdmin.readonly_fields) + list(self.readonly_fields))
278@admin.register(EditorialDecision)
279class EditorialDecisionAdmin(BaseUserChangeTrackingAdmin):
280 inlines = (get_file_wrapper_inline(EditorialDecisionFile),)
281 fieldsets = [
282 (
283 None,
284 {
285 "fields": [
286 "version",
287 "value",
288 "date_created",
289 "created_by",
290 "comment",
291 "last_modified_by",
292 "date_last_modified",
293 ]
294 },
295 )
296 ]
298 list_display = ["version", "value", "date_created", "created_by", "comment"]
299 readonly_fields = ["version"]
301 def get_readonly_fields(self, request: HttpRequest, obj) -> set[str]:
302 return set(list(BaseUserChangeTrackingAdmin.readonly_fields) + list(self.readonly_fields))
305@admin.register(SuggestedReviewer)
306class SuggestedReviewerAdmin(admin.ModelAdmin):
307 list_display = ["first_name", "last_name", "email"]
310@admin.register(Suggestion)
311class SuggestionAdmin(admin.ModelAdmin):
312 list_display = ["submission", "suggested_reviewer", "suggested_user", "suggest_to_avoid"]