Changeset View
Changeset View
Standalone View
Standalone View
training/models/sections.py
| from django.db import models | from django.db import models | ||||
| from django.urls.base import reverse | from django.urls.base import reverse | ||||
| from django.utils.text import slugify | from django.utils.text import slugify | ||||
| from taggit.managers import TaggableManager | from taggit.managers import TaggableManager | ||||
| from comments.models import Comment | from comments.models import Comment | ||||
| from common import mixins | from common import mixins | ||||
| from common.upload_paths import get_upload_to_hashed_path | from common.upload_paths import get_upload_to_hashed_path | ||||
| from static_assets.models import StorageLocation | |||||
| from training.models import chapters | from training.models import chapters | ||||
| class Section(mixins.CreatedUpdatedMixin, models.Model): | class Section(mixins.CreatedUpdatedMixin, models.Model): | ||||
| class Meta: | class Meta: | ||||
| constraints = [ | constraints = [ | ||||
| models.UniqueConstraint(fields=['chapter', 'index'], name='unique_index_per_section'), | models.UniqueConstraint(fields=['chapter', 'index'], name='unique_index_per_section'), | ||||
| models.UniqueConstraint(fields=['chapter', 'slug'], name='unique_slug_per_section'), | models.UniqueConstraint(fields=['chapter', 'slug'], name='unique_slug_per_section'), | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | class Meta: | ||||
| models.UniqueConstraint(fields=['comment'], name='unique_section_per_comment') | models.UniqueConstraint(fields=['comment'], name='unique_section_per_comment') | ||||
| ] | ] | ||||
| section = models.ForeignKey(Section, on_delete=models.CASCADE) | section = models.ForeignKey(Section, on_delete=models.CASCADE) | ||||
| comment = models.ForeignKey(Comment, on_delete=models.CASCADE) | comment = models.ForeignKey(Comment, on_delete=models.CASCADE) | ||||
| class Video(mixins.CreatedUpdatedMixin, models.Model): | class Video(mixins.CreatedUpdatedMixin, models.Model): | ||||
| storage_location = models.ForeignKey(StorageLocation, on_delete=models.PROTECT, editable=False) | |||||
| section = models.OneToOneField(Section, on_delete=models.CASCADE, related_name='video') | section = models.OneToOneField(Section, on_delete=models.CASCADE, related_name='video') | ||||
| file = models.FileField(upload_to=get_upload_to_hashed_path) | file = models.FileField(upload_to=get_upload_to_hashed_path) | ||||
| size_bytes = models.BigIntegerField(editable=False) | size_bytes = models.BigIntegerField(editable=False) | ||||
| duration = models.DurationField(help_text='[DD] [[HH:]MM:]ss[.uuuuuu]') | duration = models.DurationField(help_text='[DD] [[HH:]MM:]ss[.uuuuuu]') | ||||
| duration.description = 'Video duration in the format [DD] [[HH:]MM:]ss[.uuuuuu]' | duration.description = 'Video duration in the format [DD] [[HH:]MM:]ss[.uuuuuu]' | ||||
| def __str__(self) -> str: | def __str__(self) -> str: | ||||
| return self.file.name # type: ignore | return self.file.name # type: ignore | ||||
| @property | @property | ||||
| def progress_url(self) -> str: | def progress_url(self) -> str: | ||||
| return reverse('video-progress', kwargs={'video_pk': self.pk}) | return reverse('video-progress', kwargs={'video_pk': self.pk}) | ||||
| def clean(self): | def clean(self): | ||||
| super().clean() | super().clean() | ||||
| if self.file: | if self.file: | ||||
| self.size_bytes = self.file.size | self.size_bytes = self.file.size | ||||
| if self.section: | |||||
| self.storage_location = self.section.chapter.training.storage_location | |||||
| class Asset(mixins.CreatedUpdatedMixin, models.Model): | class Asset(mixins.CreatedUpdatedMixin, models.Model): | ||||
| storage_location = models.ForeignKey(StorageLocation, on_delete=models.PROTECT, editable=False) | |||||
| section = models.ForeignKey(Section, on_delete=models.CASCADE, related_name='assets') | section = models.ForeignKey(Section, on_delete=models.CASCADE, related_name='assets') | ||||
| file = models.FileField(upload_to=get_upload_to_hashed_path) | file = models.FileField(upload_to=get_upload_to_hashed_path) | ||||
| size_bytes = models.IntegerField(editable=False) | size_bytes = models.IntegerField(editable=False) | ||||
| def __str__(self) -> str: | def __str__(self) -> str: | ||||
| return self.file.name # type: ignore | return self.file.name # type: ignore | ||||
| def clean(self): | def clean(self): | ||||
| super().clean() | super().clean() | ||||
| if self.file: | if self.file: | ||||
| self.size_bytes = self.file.size | self.size_bytes = self.file.size | ||||
| if self.section: | |||||
| self.storage_location = self.section.chapter.training.storage_location | |||||