aboutsummaryrefslogtreecommitdiffstats
path: root/alphabetlearning/resources/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'alphabetlearning/resources/models.py')
-rw-r--r--alphabetlearning/resources/models.py201
1 files changed, 201 insertions, 0 deletions
diff --git a/alphabetlearning/resources/models.py b/alphabetlearning/resources/models.py
new file mode 100644
index 0000000..3dfad06
--- /dev/null
+++ b/alphabetlearning/resources/models.py
@@ -0,0 +1,201 @@
+from django.conf import settings
+from django.db import models
+from django.urls import reverse
+
+from .s3 import get_presigned_obj_url
+
+CURRICULUM_CHOICES = [
+ ("No curriculum", "No curriculum"),
+ ("English", "English"),
+ ("Scottish", "Scottish"),
+]
+
+AGE_RANGE_CHOICES = [
+ ("Preschool (3-4yrs)", "Preschool (3-4yrs)"),
+ ("Nursery (2-5yrs)", "Nursery (2-5yrs)"),
+ ("Reception (4-5yrs)", "Reception (4-5yrs)"),
+ ("Year 1 (5-6yrs)", "Year 1 (5-6yrs)"),
+ ("Year 2 (6-7yrs)", "Year 2 (6-7yrs)"),
+ ("Early Years (0-5yrs)", "Early Years (0-5yrs)"),
+ ("Keystage 1 (5-7yrs)", "Keystage 1 (5-7yrs)"),
+ ("Keystage 2 (7-11yrs)", "Keystage 2 (7-11yrs)"),
+ ("Age not applicable", "Age not applicable"),
+]
+
+DESC_HELP_TEXT = """
+ <strong>Markdown acceptable here!</strong>This is your opportunity to clearly explain what
+ your resource is all about! It’s worth remembering that you are using the space to
+ communicate to two different audiences. Firstly, think about what fellow teachers
+ would like to know, such as exactly what the resource contains and how it could be used in
+ the classroom. Secondly, the words you include on this page are also talking to internal and
+ external search engines. External search engines, like Google, show the first 155 characters
+ of the resource description, so make sure you take advantage
+ of these characters by using lots of relevant keywords as part of an enticing pitch.
+"""
+
+
+# Create your models here.
+class Resource(models.Model):
+ name = models.CharField(max_length=255, null=False)
+ price = models.DecimalField(
+ max_digits=6,
+ decimal_places=2,
+ default=0.00,
+ null=False,
+ blank=False,
+ )
+ thumbnail_filenames = models.JSONField(
+ null=False,
+ verbose_name="Thumbnail filenames",
+ default=list,
+ )
+ resource_type = models.ForeignKey("ResourceType", on_delete=models.CASCADE)
+ main_resource_category = models.ForeignKey(
+ "ResourceCategory",
+ on_delete=models.CASCADE,
+ null=False,
+ related_name="main_resource_category",
+ )
+ subcategories = models.ManyToManyField(
+ "ResourceSubcategory",
+ blank=True,
+ related_name="additional_resource_category",
+ )
+ description = models.TextField(
+ max_length=5000,
+ null=False,
+ blank=False,
+ help_text=DESC_HELP_TEXT,
+ )
+ card_description = models.TextField(
+ max_length=1000,
+ blank=True,
+ default="",
+ help_text=(
+ "If you enter text here, it will be used in the 'card' "
+ "description box on the home page. Max 1000 characters."
+ ),
+ )
+ age_range = models.CharField(
+ max_length=20,
+ null=False,
+ default="5-7",
+ blank=False,
+ choices=AGE_RANGE_CHOICES,
+ )
+ curriculum = models.CharField(
+ max_length=20,
+ default="English",
+ blank=True,
+ null=True,
+ choices=[
+ ("No curriculum", "No curriculum"),
+ ("English", "English"),
+ ("Scottish", "Scottish"),
+ ],
+ )
+ feature_slot = models.IntegerField(
+ choices=((1, 1), (2, 2), (3, 3)),
+ unique=True,
+ null=True,
+ blank=True,
+ default=0,
+ )
+ created_at = models.DateTimeField(auto_now_add=True)
+ updated_at = models.DateTimeField(auto_now=True)
+
+ def __str__(self):
+ return self.name
+
+ def get_pdf_file_names(self):
+ return [p.file_name for p in self.pdf_resources.all()]
+
+ def get_pdf_snapshot_file_names(self):
+ rs = self.pdf_resources.all()
+ sh = [sh for sh in rs.values_list("pdf_page_snapshots__file_name", flat=True)]
+ return [s for s in sh if s]
+
+ def get_absolute_url(self):
+ return reverse("resources:resource_detail", kwargs={"resource_id": self.pk})
+
+ def thumbnail_urls(self) -> list[str]:
+ return [
+ get_presigned_obj_url(settings.AWS_STORAGE_BUCKET_NAME, f"thumbnails/{f}")
+ for f in self.thumbnail_filenames
+ ]
+
+
+class ResourceType(models.Model):
+ name = models.CharField(max_length=255, null=False)
+ created_at = models.DateTimeField(auto_now_add=True)
+ updated_at = models.DateTimeField(auto_now=True)
+
+ class Meta:
+ verbose_name_plural = "Resource Types"
+
+ def __str__(self):
+ return self.name
+
+
+class ResourceSubcategory(models.Model):
+ name = models.CharField(max_length=255, null=False)
+ created_at = models.DateTimeField(auto_now_add=True)
+ updated_at = models.DateTimeField(auto_now=True)
+
+ class Meta:
+ verbose_name_plural = "Resource Subcategories"
+
+ def __str__(self):
+ return self.name
+
+
+class ResourceCategory(models.Model):
+ name = models.CharField(max_length=255, null=False)
+ created_at = models.DateTimeField(auto_now_add=True)
+ updated_at = models.DateTimeField(auto_now=True)
+ colour_css_class = models.CharField(max_length=56, blank=True, null=True)
+ badge_foreground_colour = models.CharField(max_length=56, blank=True, null=True)
+
+ class Meta:
+ verbose_name_plural = "Resource Categories"
+
+ def __str__(self):
+ return self.name
+
+
+class PDFResource(models.Model):
+ resource = models.ForeignKey(
+ "Resource",
+ on_delete=models.CASCADE,
+ null=False,
+ related_name="pdf_resources",
+ )
+ file_name = models.CharField(max_length=255, null=False)
+ file_size = models.IntegerField(null=False)
+
+ class Meta:
+ verbose_name_plural = "PDF Resources"
+ unique_together = ("resource", "file_name")
+
+ def __str__(self):
+ return self.resource.name
+
+ def snapshot_file_names(self):
+ return [f.file_name for f in self.pdf_page_snapshots.all()]
+
+
+class PDFPageSnapshot(models.Model):
+ name = models.CharField(max_length=255, null=False)
+ file_name = models.CharField(max_length=255, null=False)
+ pdf_file = models.ForeignKey(
+ "PDFResource",
+ on_delete=models.CASCADE,
+ null=False,
+ related_name="pdf_page_snapshots",
+ )
+
+ class Meta:
+ verbose_name_plural = "PDF Page Snapshots"
+
+ def __str__(self):
+ return self.name