Skip to content

Commit

Permalink
Add URL routing for catalog for courses/programs and department (#2140)
Browse files Browse the repository at this point in the history
* add to urls.js

* update for tab/dept

* take state out of constructor

* adding slug field

* slug migration and adding to management command

* fixing routing with new slug stuff and routes in order

* successful introduction of slug to the page

* FIxed routing to further pages and fake pages

* tests and formatting

* Test Fix

* fixing migrations

* fixed js test finally

* well that was silly
  • Loading branch information
JenniWhitman authored Apr 1, 2024
1 parent 2c79e46 commit 0a8d37c
Show file tree
Hide file tree
Showing 12 changed files with 519 additions and 131 deletions.
1 change: 1 addition & 0 deletions courses/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ class DepartmentAdmin(admin.ModelAdmin):
"""Admin for Department"""

model = Department
list_display = ("name", "slug")


class BlockedCountryAdmin(TimestampedModelAdmin):
Expand Down
6 changes: 3 additions & 3 deletions courses/management/commands/create_courseware.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
a course run).
"""

from typing import Union
from django.db import models
from typing import List
from typing import List, Union

from django.core.management import BaseCommand
from django.db import models
from django.utils.text import slugify

from courses.models import Course, CourseRun, Department, Program
from main.utils import parse_supplied_date
Expand Down
20 changes: 20 additions & 0 deletions courses/migrations/0048_add_department_slug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.2.23 on 2024-03-27 14:49

from django.db import migrations, models


# Running this migration across 3 files to support the unique field, per django docs:
# https://docs.djangoproject.com/en/4.2/howto/writing-migrations/#migrations-that-add-unique-fields
class Migration(migrations.Migration):

dependencies = [
("courses", "0047_courses_and_programs_department_required"),
]

operations = [
migrations.AddField(
model_name="department",
name="slug",
field=models.SlugField(max_length=255, null=True),
),
]
22 changes: 22 additions & 0 deletions courses/migrations/0049_populate_department_slug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 3.2.23 on 2024-03-27 15:35

from django.db import migrations
from django.utils.text import slugify


def generate_slug(apps, schema):
Department = apps.get_model("courses", "Department")
for department in Department.objects.all():
department.slug = slugify(department.name)
department.save(update_fields=["slug"])


class Migration(migrations.Migration):

dependencies = [
("courses", "0048_add_department_slug"),
]

operations = [
migrations.RunPython(generate_slug, reverse_code=migrations.RunPython.noop),
]
18 changes: 18 additions & 0 deletions courses/migrations/0050_make_department_slug_unique.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.23 on 2024-03-27 15:35

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("courses", "0049_populate_department_slug"),
]

operations = [
migrations.AlterField(
model_name="department",
name="slug",
field=models.SlugField(max_length=128, unique=True),
),
]
7 changes: 7 additions & 0 deletions courses/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from django.db.models import Q
from django.db.models.constraints import CheckConstraint, UniqueConstraint
from django.utils.functional import cached_property
from django.utils.text import slugify
from django_countries.fields import CountryField
from mitol.common.models import TimestampedModel
from mitol.common.utils.collections import first_matching_item
Expand Down Expand Up @@ -110,10 +111,16 @@ class Department(TimestampedModel):
"""

name = models.CharField(max_length=128, unique=True)
slug = models.SlugField(max_length=128, unique=True)

def __str__(self):
return self.name

def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)


class Program(TimestampedModel, ValidateOnSaveMixin):
"""Model for a course program"""
Expand Down
2 changes: 1 addition & 1 deletion courses/serializers/v2/departments.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class DepartmentSerializer(serializers.ModelSerializer):

class Meta:
model = Department
fields = ["id", "name"]
fields = ["id", "name", "slug"]


class DepartmentWithCoursesAndProgramsSerializer(DepartmentSerializer):
Expand Down
15 changes: 7 additions & 8 deletions courses/serializers/v2/departments_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
from courses.factories import (
CourseFactory,
CourseRunFactory,
ProgramFactory,
DepartmentFactory,
ProgramFactory,
)
from courses.serializers.v2.departments import (
DepartmentSerializer,
DepartmentWithCoursesAndProgramsSerializer,
)

from main.test_utils import assert_drf_json_equal


def test_serialize_department(mock_context):
department = DepartmentFactory.create()
data = DepartmentSerializer(instance=department, context=mock_context).data

assert_drf_json_equal(data, {"id": department.id, "name": department.name})
assert_drf_json_equal(
data, {"id": department.id, "name": department.name, "slug": department.slug}
)


# Should return 0 when there are no courses or programs at all, or when there are, but none are relevant
Expand All @@ -34,6 +35,7 @@ def test_serialize_department_with_courses_and_programs__no_related(mock_context
"name": department.name,
"course_ids": [],
"program_ids": [],
"slug": department.slug,
},
)

Expand All @@ -50,6 +52,7 @@ def test_serialize_department_with_courses_and_programs__no_related(mock_context
"name": department.name,
"course_ids": [],
"program_ids": [],
"slug": department.slug,
},
)

Expand All @@ -69,9 +72,6 @@ def test_serialize_department_with_courses_and_programs__with_multiples(
valid_course_id_list = []
valid_program_id_list = []

invalid_courses_list = []
invalid_programs_list = []

vc = valid_courses
while vc > 0:
course = CourseFactory.create(departments=[department])
Expand All @@ -85,10 +85,8 @@ def test_serialize_department_with_courses_and_programs__with_multiples(
valid_program_id_list.append(ProgramFactory.create(departments=[department]).id)
vp -= 1
while invalid_courses > 0:
# invalid_courses_list += [CourseFactory.create()]
invalid_courses -= 1
while invalid_programs > 0:
# invalid_programs_list += [ProgramFactory.create()]
invalid_programs -= 1
data = DepartmentWithCoursesAndProgramsSerializer(
instance=department, context=mock_context
Expand All @@ -100,5 +98,6 @@ def test_serialize_department_with_courses_and_programs__with_multiples(
"name": department.name,
"course_ids": valid_course_id_list,
"program_ids": valid_program_id_list,
"slug": department.slug,
},
)
8 changes: 8 additions & 0 deletions frontend/public/src/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ export class App extends React.Component<Props, void> {
path={urljoin(match.url, String(routes.learnerRecords))}
component={LearnerRecordsPage}
/>
<Route
path={urljoin(match.url, String(routes.catalogTabByDepartment))}
component={CatalogPage}
/>
<Route
path={urljoin(match.url, String(routes.catalogTab))}
component={CatalogPage}
/>
<Route
path={urljoin(match.url, String(routes.catalog))}
component={CatalogPage}
Expand Down
Loading

0 comments on commit 0a8d37c

Please sign in to comment.