Skip to content

Commit 1978afb

Browse files
committed
WIP on JournalManager
1 parent 6bf0c83 commit 1978afb

3 files changed

Lines changed: 102 additions & 100 deletions

File tree

src/journal/models.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from django.utils import timezone, translation
3434
from django.utils.functional import cached_property
3535
from django.utils.translation import gettext, gettext_lazy as _
36+
from modeltranslation.utils import build_localized_fieldname
3637

3738
from core import (
3839
files,
@@ -97,6 +98,97 @@ def issue_large_image_path(instance, filename):
9798
return os.path.join(path, filename)
9899

99100

101+
class JournalManager(models.Manager):
102+
def _apply_ordering_az(self, journals):
103+
"""
104+
Order a queryset of journals A-Z on English-language journal name.
105+
Note that this does not support multilingual journal names:
106+
more work is needed on django-modeltranslation to
107+
support Django subqueries.
108+
:param journals: Queryset of Journal objects
109+
"""
110+
localized_column = build_localized_fieldname(
111+
"value",
112+
settings.LANGUAGE_CODE, # Assumed to be 'en' in default config
113+
)
114+
name = core_models.SettingValue.objects.filter(
115+
journal=models.OuterRef("pk"),
116+
setting__name="journal_name",
117+
)
118+
journals.annotate(
119+
journal_name=models.Subquery(
120+
name.values_list(localized_column, flat=True)[:1],
121+
output_field=models.CharField(),
122+
)
123+
)
124+
return journals.order_by("journal_name")
125+
126+
def _apply_ordering(self, journals):
127+
press = press_models.Press.objects.all().first()
128+
if press.order_journals_az:
129+
return self._apply_ordering_az(journals)
130+
else:
131+
# Journals will already have been ordered according to Meta.ordering
132+
return journals
133+
134+
@property
135+
def public_journals(self):
136+
"""
137+
Get all journals that are not hidden from the press
138+
or designated as conferences.
139+
Do not apply ordering yet,
140+
since the caller may filter the queryset.
141+
"""
142+
return self.get_queryset().filter(
143+
hide_from_press=False,
144+
is_conference=False,
145+
)
146+
147+
@property
148+
def public_active_journals(self):
149+
"""
150+
Get all journals that are visible to the press
151+
and marked as 'Active' or 'Test' in the publishing status field.
152+
153+
Note: Test journals are included so that users can test the journal
154+
list safely. A separate mechanism exists to hide them from the press
155+
once the press enters normal operation:
156+
Journal.hide_from_press.
157+
"""
158+
return self._apply_ordering(
159+
self.public_journals.filter(
160+
status__in=[
161+
Journal.PublishingStatus.ACTIVE,
162+
Journal.PublishingStatus.TEST,
163+
]
164+
)
165+
)
166+
167+
@property
168+
def public_archived_journals(self):
169+
"""
170+
Get all journals that are visible to the press
171+
and marked as 'Archived' in the publishing status field.
172+
"""
173+
return self._apply_ordering(
174+
self.public_journals.filter(
175+
status=Journal.PublishingStatus.ARCHIVED,
176+
)
177+
)
178+
179+
@property
180+
def public_coming_soon_journals(self):
181+
"""
182+
Get all journals that are visible to the press
183+
and marked as 'Coming soon' in the publishing status field.
184+
"""
185+
return self._apply_ordering(
186+
self.public_journals.filter(
187+
status=Journal.PublishingStatus.COMING_SOON,
188+
)
189+
)
190+
191+
100192
class Journal(AbstractSiteModel):
101193
AUTH_SUCCESS_URL = "core_dashboard"
102194

@@ -311,6 +403,8 @@ class PublishingStatus(models.TextChoices):
311403

312404
disable_front_end = models.BooleanField(default=False)
313405

406+
objects = JournalManager()
407+
314408
class Meta:
315409
ordering = ("sequence",)
316410
# Note that we also commonly want to order journals A-Z by name.

src/press/models.py

Lines changed: 4 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from django.core.validators import MinValueValidator
1515
from django.db import models
1616
from django.utils import timezone
17-
from modeltranslation.utils import build_localized_fieldname
1817
from django.apps import apps
1918

2019
from core import models as core_models
@@ -211,7 +210,7 @@ def get_press(request):
211210
def journals(self, **filters):
212211
Journal = apps.get_model("journal", "Journal")
213212
journals = Journal.objects.filter(**filters)
214-
return self.apply_journal_ordering(journals)
213+
return Journal.objects._apply_ordering(journals)
215214

216215
@property
217216
def active_news_items(self):
@@ -373,7 +372,8 @@ def publishes_conferences(self):
373372

374373
@property
375374
def publishes_journals(self):
376-
return self.public_journals.count() > 0
375+
Journal = apps.get_model("journal", "Journal")
376+
return Journal.objects.public_journals.count() > 0
377377

378378
@cache(600)
379379
def live_repositories(self):
@@ -428,37 +428,6 @@ def navigation_items_for_sitemap(self):
428428
def code(self):
429429
return "press"
430430

431-
def apply_journal_ordering_az(self, journals):
432-
"""
433-
Order a queryset of journals A-Z on English-language journal name.
434-
Note that this does not support multilingual journal names:
435-
more work is needed on django-modeltranslation to
436-
support Django subqueries.
437-
:param journals: Queryset of Journal objects
438-
"""
439-
localized_column = build_localized_fieldname(
440-
"value",
441-
settings.LANGUAGE_CODE, # Assumed to be 'en' in default config
442-
)
443-
name = core_models.SettingValue.objects.filter(
444-
journal=models.OuterRef("pk"),
445-
setting__name="journal_name",
446-
)
447-
journals.annotate(
448-
journal_name=models.Subquery(
449-
name.values_list(localized_column, flat=True)[:1],
450-
output_field=models.CharField(),
451-
)
452-
)
453-
return journals.order_by("journal_name")
454-
455-
def apply_journal_ordering(self, journals):
456-
if self.order_journals_az:
457-
return self.apply_journal_ordering_az(journals)
458-
else:
459-
# Journals will already have been ordered according to Meta.ordering
460-
return journals
461-
462431
@property
463432
def journals_az(self):
464433
"""
@@ -469,68 +438,7 @@ def journals_az(self):
469438
"Use `Press.journals` with Press.order_journals_az turned on."
470439
)
471440
Journal = apps.get_model("journal", "Journal")
472-
return self.apply_journal_ordering_az(Journal.objects.all())
473-
474-
@property
475-
def public_journals(self):
476-
"""
477-
Get all journals that are not hidden from the press
478-
or designated as conferences.
479-
Do not apply ordering yet,
480-
since the caller may filter the queryset.
481-
"""
482-
Journal = apps.get_model("journal", "Journal")
483-
return Journal.objects.filter(
484-
hide_from_press=False,
485-
is_conference=False,
486-
)
487-
488-
@property
489-
def public_active_journals(self):
490-
"""
491-
Get all journals that are visible to the press
492-
and marked as 'Active' or 'Test' in the publishing status field.
493-
494-
Note: Test journals are included so that users can test the journal
495-
list safely. A separate mechanism exists to hide them from the press
496-
once the press enters normal operation:
497-
Journal.hide_from_press.
498-
"""
499-
Journal = apps.get_model("journal.Journal")
500-
return self.apply_journal_ordering(
501-
self.public_journals.filter(
502-
status__in=[
503-
Journal.PublishingStatus.ACTIVE,
504-
Journal.PublishingStatus.TEST,
505-
]
506-
)
507-
)
508-
509-
@property
510-
def public_archived_journals(self):
511-
"""
512-
Get all journals that are visible to the press
513-
and marked as 'Archived' in the publishing status field.
514-
"""
515-
Journal = apps.get_model("journal.Journal")
516-
return self.apply_journal_ordering(
517-
self.public_journals.filter(
518-
status=Journal.PublishingStatus.ARCHIVED,
519-
)
520-
)
521-
522-
@property
523-
def public_coming_soon_journals(self):
524-
"""
525-
Get all journals that are visible to the press
526-
and marked as 'Coming soon' in the publishing status field.
527-
"""
528-
Journal = apps.get_model("journal.Journal")
529-
return self.apply_journal_ordering(
530-
self.public_journals.filter(
531-
status=Journal.PublishingStatus.COMING_SOON,
532-
)
533-
)
441+
return Journal.objects._apply_ordering_az(Journal.objects.filter())
534442

535443
@property
536444
def published_articles(self):

src/press/views.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,10 @@ def journals(request):
125125
template = "press/press_journals.html"
126126

127127
context = {
128-
"active_journals": request.press.public_active_journals,
129-
"archived_journals": request.press.public_archived_journals,
130-
"coming_soon_journals": request.press.public_coming_soon_journals,
131-
"journals": request.press.public_journals, # Backwards compatibility
128+
"active_journals": journal_models.Journal.objects.public_active_journals,
129+
"archived_journals": journal_models.Journal.objects.public_archived_journals,
130+
"coming_soon_journals": journal_models.Journal.objects.public_coming_soon_journals,
131+
"journals": journal_models.Journal.objects.public_journals, # Backwards compatibility
132132
}
133133

134134
return render(request, template, context)

0 commit comments

Comments
 (0)