Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1301 - PROGRAMME FINDER | MRes Healthcare & Design and MRes RCA #1069

Merged
merged 9 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions rca/enquire_to_study/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@
EnquiryFormSubmission,
EnquiryFormSubmissionProgrammesOrderable,
)
from rca.programmes.factories import ProgrammePageFactory
from rca.programmes.factories import (
ProgrammePageFactory,
ProgrammePageProgrammeTypeFactory,
ProgrammeTypeFactory,
)


class TestEnquireToStudyForm(TestCase):
def setUp(self):
self.start_date = StartDateFactory(qs_code="test-code")
self.enquiry_reason = EnquiryReasonFactory()
page = ProgrammePageFactory(qs_code=1)
ProgrammePageProgrammeTypeFactory(
page=page, programme_type=ProgrammeTypeFactory()
)
self.form_data = {
"first_name": "Monty",
"last_name": "python",
Expand All @@ -25,7 +33,7 @@ def setUp(self):
"country_of_residence": "GB",
"city": "Bristol",
"country_of_citizenship": "GB",
"programmes": [ProgrammePageFactory(qs_code=1, programme_type__pk=2).pk],
"programmes": [page.pk],
"start_date": self.start_date.pk,
"enquiry_reason": self.enquiry_reason.pk,
"enquiry_questions": "What is your name?",
Expand Down
12 changes: 10 additions & 2 deletions rca/enquire_to_study/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
from rca.enquire_to_study.models import EnquireToStudySettings, EnquiryFormSubmission
from rca.enquire_to_study.views import EnquireToStudyFormView
from rca.enquire_to_study.wagtail_hooks import EnquiryFormSubmissionAdmin
from rca.programmes.factories import ProgrammePageFactory
from rca.programmes.factories import (
ProgrammePageFactory,
ProgrammePageProgrammeTypeFactory,
ProgrammeTypeFactory,
)


class EnquireToStudyFormViewTest(TestCase):
Expand Down Expand Up @@ -54,6 +58,10 @@ def setUp(self):
email_content="Test email content",
site_id=Site.objects.get().pk,
)
page = ProgrammePageFactory(qs_code=1)
ProgrammePageProgrammeTypeFactory(
page=page, programme_type=ProgrammeTypeFactory()
)

self.form_data = {
"first_name": "Monty",
Expand All @@ -63,7 +71,7 @@ def setUp(self):
"country_of_residence": "GB",
"city": "Bristol",
"country_of_citizenship": "GB",
"programmes": [ProgrammePageFactory(qs_code=1, programme_type__pk=2).pk],
"programmes": [page.pk],
"start_date": StartDateFactory(qs_code="test-code").pk,
"enquiry_reason": EnquiryReasonFactory().pk,
"enquiry_questions": "What is your name?",
Expand Down
15 changes: 13 additions & 2 deletions rca/programmes/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
import wagtail_factories
from faker import Factory as FakerFactory

from .models import DegreeLevel, ProgrammePage, ProgrammeType
from .models import (
DegreeLevel,
ProgrammePage,
ProgrammePageProgrammeType,
ProgrammeType,
)

faker = FakerFactory.create()

Expand Down Expand Up @@ -31,4 +36,10 @@ class Meta:
scholarships_information = factory.Faker("text", max_nb_chars=100)
search_description = factory.Faker("text", max_nb_chars=25)
degree_level = factory.SubFactory(DegreeLevelFactory)
programme_type = factory.SubFactory(ProgrammeTypeFactory)


class ProgrammePageProgrammeTypeFactory(factory.django.DjangoModelFactory):
class Meta:
model = ProgrammePageProgrammeType

page = factory.SubFactory(ProgrammePageFactory)
44 changes: 44 additions & 0 deletions rca/programmes/migrations/0093_programmepageprogrammetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 4.2.16 on 2025-01-14 14:23

from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields


class Migration(migrations.Migration):

dependencies = [
("programmes", "0092_link_block_url_label"),
]

operations = [
migrations.CreateModel(
name="ProgrammePageProgrammeType",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"page",
modelcluster.fields.ParentalKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="programme_types",
to="programmes.programmepage",
),
),
(
"programme_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="programmes.programmetype",
),
),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 4.2.16 on 2025-01-14 14:25

from django.db import migrations

def migrate_programme_type_to_programme_types(apps, schema_editor):
# Get the models
ProgrammePage = apps.get_model("programmes", "ProgrammePage")
ProgrammePageProgrammeType = apps.get_model("programmes", "ProgrammePageProgrammeType")

for page in ProgrammePage.objects.all():
if programme_type := page.programme_type:
ProgrammePageProgrammeType.objects.create(
page_id=page.id,
programme_type=programme_type,
)


class Migration(migrations.Migration):

dependencies = [
("programmes", "0093_programmepageprogrammetype"),
]

operations = [
migrations.RunPython(migrate_programme_type_to_programme_types, reverse_code=migrations.RunPython.noop),
]
17 changes: 17 additions & 0 deletions rca/programmes/migrations/0095_remove_programme_type_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.16 on 2025-01-17 08:54

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("programmes", "0094_migrate_programme_type_to_programme_types"),
]

operations = [
migrations.RemoveField(
model_name="programmepage",
name="programme_type",
),
]
37 changes: 23 additions & 14 deletions rca/programmes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ def get_fake_slug(self):
return slugify(self.display_name)


class ProgrammePageProgrammeType(models.Model):
page = ParentalKey("programmes.ProgrammePage", related_name="programme_types")
programme_type = models.ForeignKey(
"programmes.ProgrammeType",
on_delete=models.CASCADE,
)
panels = [FieldPanel("programme_type")]

def __str__(self):
return self.programme_type.title


class ProgrammePageRelatedSchoolsAndResearchPages(RelatedPage):
source_page = ParentalKey(
"ProgrammePage", related_name="related_schools_and_research_pages"
Expand Down Expand Up @@ -330,13 +342,6 @@ class ProgrammePage(TapMixin, ContactFieldsMixin, BasePage):
degree_level = models.ForeignKey(
DegreeLevel, on_delete=models.SET_NULL, blank=False, null=True, related_name="+"
)
programme_type = models.ForeignKey(
ProgrammeType,
on_delete=models.SET_NULL,
blank=False,
null=True,
related_name="+",
)
hero_image = models.ForeignKey(
"images.CustomImage",
null=True,
Expand Down Expand Up @@ -615,10 +620,7 @@ class ProgrammePage(TapMixin, ContactFieldsMixin, BasePage):
# Taxonomy, relationships etc
FieldPanel("degree_level"),
InlinePanel("subjects", label="Subjects"),
FieldPanel(
"programme_type",
help_text="Used to show content related to this programme page",
),
InlinePanel("programme_types", label="Programme Types"),
MultiFieldPanel(
[
FieldPanel("hero_image"),
Expand Down Expand Up @@ -844,7 +846,14 @@ class ProgrammePage(TapMixin, ContactFieldsMixin, BasePage):
index.SearchField("scholarship_accordion_items"),
index.SearchField("scholarship_information_blocks"),
index.SearchField("more_information_blocks", boost=2),
index.RelatedFields("programme_type", [index.SearchField("display_name")]),
index.RelatedFields(
"programme_types",
[
index.RelatedFields(
"programme_type", [index.SearchField("display_name")]
)
],
),
index.RelatedFields(
"programme_locations",
[index.RelatedFields("programme_location", [index.SearchField("title")])],
Expand Down Expand Up @@ -876,7 +885,7 @@ class ProgrammePage(TapMixin, ContactFieldsMixin, BasePage):
api_fields = [
# Fields for filtering and display, shared with shortcourses.ShortCoursePage.
APIField("subjects"),
APIField("programme_type"),
APIField("programme_types"),
APIField("related_schools_and_research_pages"),
APIField(
"summary",
Expand Down Expand Up @@ -1169,7 +1178,7 @@ def get_context(self, request, *args, **kwargs):

filters = [
{"id": "subjects", "title": "Subject", "items": subjects},
{"id": "programme_type", "title": "Type", "items": programme_types},
{"id": "programme_types", "title": "Type", "items": programme_types},
{
"id": "related_schools_and_research_pages",
"title": "Schools & centres",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ <h3 class="related-content__title heading heading--five" property="schema:name">
<svg width="12" height="8" class="related-content__icon" aria-hidden="true"><use xlink:href="#arrow"></use></svg>
</a>
</h3>
<p class="related-content__degree body body--one" property="schema:EducationalCredentialAwarded">{% firstof related_item.degree_level related_item.programme_type %}</p>
{% with programme_types=related_item.programme_types.all %}
{% if related_item.degree_levels %}
<p class="related-content__degree body body--one" property="schema:EducationalCredentialAwarded">{{ related_item.degree_level }}</p>
{% else %}
<p class="related-content__degree body body--one" property="schema:EducationalCredentialAwarded">
{% for item in programme_types %}
{{ item.programme_type.display_name }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% endif %}
{% endwith %}
</div>
<p class="related-content__copy body body--one" property="schema:description">
{% firstof related_item.programme_description_subtitle related_item.introduction related_item.listing_summary %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,25 @@ <h3 class="related-content__title body body--one" property="schema:name">
<svg width="12" height="8" class="related-content__icon" aria-hidden="true"><use xlink:href="#arrow"></use></svg>
</a>
</h3>
{% if related_item.degree_level %}
<p class="related-content__degree body body--two" property="schema:EducationalCredentialAwarded">{{ related_item.degree_level }}</p>
{% elif related_item.programme_type %}
<p class="related-content__degree body body--two">{{ related_item.booking_summary|default:related_item.programme_type }}</p>
{% elif related_item.meta %}
<p class="related-content__degree body body--two">{{ related_item.meta }}</p>
{% elif related_item.get_verbose_name == 'Guide page' %}
<p class="related-content__degree body body--two">Guide</p>
{% endif %}
{% with programme_types=related_item.programme_types.all %}
{% if related_item.degree_level %}
<p class="related-content__degree body body--two" property="schema:EducationalCredentialAwarded">{{ related_item.degree_level }}</p>
{% elif programme_types %}
{% if related_item.booking_summary %}
<p class="related-content__degree body body--two">{{ related_item.booking_summary }}</p>
{% else %}
<p class="related-content__degree body body--two">
{% for item in programme_types %}
{{ item.programme_type.display_name }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% endif %}
{% elif related_item.meta %}
<p class="related-content__degree body body--two">{{ related_item.meta }}</p>
{% elif related_item.get_verbose_name == 'Guide page' %}
<p class="related-content__degree body body--two">Guide</p>
{% endif %}
{% endwith %}
</div>
<p class="related-content__copy body body--two" property="schema:description">
{% firstof related_item.programme_description_subtitle related_item.introduction|default:''|striptags related_item.listing_summary %}
Expand Down
2 changes: 1 addition & 1 deletion rca/schools/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ def get_short_courses_index_link(self):
).first()
if short_course_type:
return (
f"{self.get_programme_index_link()}?category=programme_type&"
f"{self.get_programme_index_link()}?category=programme_types&"
f"value={short_course_type.id}-{slugify(short_course_type.display_name)}"
)

Expand Down
11 changes: 9 additions & 2 deletions rca/shortcourses/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@

from rca.programmes.factories import ProgrammeTypeFactory

from .models import ShortCoursePage
from .models import ShortCoursePage, ShortCourseProgrammeType


class ShortCoursePageFactory(wagtail_factories.PageFactory):
class Meta:
model = ShortCoursePage

title = factory.Faker("text", max_nb_chars=25)
programme_type = factory.SubFactory(ProgrammeTypeFactory)
show_register_link = False


class ShortCourseProgrammeTypeFactory(factory.django.DjangoModelFactory):
class Meta:
model = ShortCourseProgrammeType

page = factory.SubFactory(ShortCoursePageFactory)
programme_type = factory.SubFactory(ProgrammeTypeFactory)
46 changes: 46 additions & 0 deletions rca/shortcourses/migrations/0039_shortcourseprogrammetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Generated by Django 4.2.16 on 2025-01-14 14:45

from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields


class Migration(migrations.Migration):

dependencies = [
("programmes", "0094_migrate_programme_type_to_programme_types"),
("shortcourses", "0038_shortcoursepage_dates"),
]

operations = [
migrations.CreateModel(
name="ShortCourseProgrammeType",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"page",
modelcluster.fields.ParentalKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="programme_types",
to="shortcourses.shortcoursepage",
),
),
(
"programme_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="short_course",
to="programmes.programmetype",
),
),
],
),
]
Loading
Loading