diff --git a/klasses/admin.py b/klasses/admin.py index a47c83339..a402a636c 100644 --- a/klasses/admin.py +++ b/klasses/admin.py @@ -28,8 +28,14 @@ class BootcampAdmin(admin.ModelAdmin): """Admin for Bootcamp""" model = models.Bootcamp - list_display = ("title",) - search_fields = ("title",) + list_display = ( + "title", + "readable_id", + ) + search_fields = ( + "title", + "readable_id", + ) inlines = [BootcampRunInline] diff --git a/klasses/factories.py b/klasses/factories.py index 91848e62d..d6cb18abb 100644 --- a/klasses/factories.py +++ b/klasses/factories.py @@ -19,6 +19,9 @@ class BootcampFactory(DjangoModelFactory): """Factory for Bootcamp""" title = FuzzyText(prefix="Bootcamp ") + readable_id = LazyAttribute( + lambda x: f"bootcamp-v1:{ random.choice(['public', 'private']) }+{FAKE.slug()}-{random.choice(['ol', 'f2f'])}" + ) class Meta: model = models.Bootcamp diff --git a/klasses/migrations/0029_bootcamp_readable_id.py b/klasses/migrations/0029_bootcamp_readable_id.py new file mode 100644 index 000000000..3ced483ca --- /dev/null +++ b/klasses/migrations/0029_bootcamp_readable_id.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.25 on 2024-04-05 16:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("klasses", "0028_add_early_bird_deadline"), + ] + + operations = [ + migrations.AddField( + model_name="bootcamp", + name="readable_id", + field=models.CharField( + blank=True, + max_length=255, + null=True, + unique=True, + help_text="The unique string to identify this bootcamp. It can be of the form " + "'bootcamp-v1:TYPE+TOPIC-FORMAT' (example: bootcamp-v1:public+IE-f2f)", + ), + ), + ] diff --git a/klasses/models.py b/klasses/models.py index ee3da878d..6ef3c80f6 100644 --- a/klasses/models.py +++ b/klasses/models.py @@ -41,6 +41,14 @@ class Bootcamp(models.Model): title = models.TextField() legacy = models.BooleanField(default=False) + readable_id = models.CharField( + null=True, + blank=True, + unique=True, + max_length=255, + help_text="The unique string to identify this bootcamp. It can be of the form 'bootcamp-v1:TYPE+TOPIC-FORMAT'" + "(example: bootcamp-v1:public+IE-f2f)", + ) def __str__(self): return "Bootcamp {title}".format(title=self.title) diff --git a/klasses/serializers.py b/klasses/serializers.py index 62e47f862..ee1a50a6b 100644 --- a/klasses/serializers.py +++ b/klasses/serializers.py @@ -23,7 +23,7 @@ class BootcampSerializer(serializers.ModelSerializer): class Meta: model = Bootcamp - fields = ["id", "title"] + fields = ["id", "title", "readable_id"] class BootcampRunSerializer(serializers.ModelSerializer): diff --git a/klasses/serializers_test.py b/klasses/serializers_test.py index 606777222..dcac8b82f 100644 --- a/klasses/serializers_test.py +++ b/klasses/serializers_test.py @@ -41,6 +41,7 @@ def test_bootcamp_serializer(): assert BootcampSerializer(bootcamp).data == { "title": bootcamp.title, "id": bootcamp.id, + "readable_id": bootcamp.readable_id, } diff --git a/localdev/seed/resources/seed_data.json b/localdev/seed/resources/seed_data.json index 45d014a2a..163c7123a 100644 --- a/localdev/seed/resources/seed_data.json +++ b/localdev/seed/resources/seed_data.json @@ -2,6 +2,7 @@ "bootcamps": [ { "title": "Single Variable Calculus", + "readable_id": "bootcamp-v1:public+SVCR-ol", "[runs]": [ { "title": "Single Variable Calculus Run 1", @@ -32,6 +33,7 @@ }, { "title": "Multivariable Calculus", + "readable_id": "bootcamp-v1:private+MCR-f2f", "[runs]": [ { "title": "Multivariable Calculus Run 1", @@ -72,6 +74,7 @@ }, { "title": "Differential Equations", + "readable_id": "bootcamp-v1:public+DER-f2f", "[runs]": [ { "title": "Differential Equations Run 1",