Files
kursy-mirror/home/models.py

149 lines
4.5 KiB
Python

from django import forms
from django.contrib.auth.models import Group, User
from django.db import models
from django.forms import CheckboxSelectMultiple
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
from taggit.models import TaggedItemBase
from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page
from wagtail.models.copying import ParentalManyToManyField
from wagtail_color_panel.fields import ColorField
from wagtail_color_panel.edit_handlers import NativeColorPanel
class EmptyPage(Page):
pass
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + ["body"]
class CoursePage(Page):
body = RichTextField(blank=True)
course_image = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
allowed_groups = ParentalManyToManyField(
Group,
related_name="course_pages",
help_text="Select a group to restrict access to this course. Non-members will be prompted to purchase the course to view modules.",
)
def _user_has_access(self, user):
if not user.is_authenticated:
return False
user_group_ids = user.groups.values_list("id", flat=True)
return self.allowed_groups.filter(id__in=user_group_ids).exists() # pyright: ignore[reportAttributeAccessIssue]
def get_context(self, request):
context = super().get_context(request)
context["user_has_access"] = self._user_has_access(request.user)
return context
content_panels = Page.content_panels + [
FieldPanel("course_image"),
FieldPanel("body"),
FieldPanel("allowed_groups", widget=CheckboxSelectMultiple),
]
class CourseModulePage(Page):
body = RichTextField(blank=True)
@property
def course(self):
if hasattr(self, "get_parent"):
parent = self.get_parent()
if parent and hasattr(parent, "specific"):
return parent.specific
return None
@property
def full_title(self):
course = self.course
if course:
return f"{course.title} - {self.title}"
return self.title
content_panels = Page.content_panels + ["body"]
class EventPageTag(TaggedItemBase):
content_object = ParentalKey(
"home.EventPage",
related_name="tagged_items",
on_delete=models.CASCADE,
)
class EventPage(Page):
tags = ClusterTaggableManager(through=EventPageTag, blank=True)
color = ColorField(default="#1c398e")
image = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
start = models.DateTimeField()
end = models.DateTimeField()
# TODO: use google maps here
location = models.CharField(max_length=255, blank=True)
max_attendees = models.PositiveIntegerField(
null=True,
blank=True,
help_text="Maximum number of attendees. Leave blank for unlimited.",
)
description = RichTextField(blank=True)
hosts = ParentalManyToManyField(
User,
related_name="hosted_events",
help_text="Select users who will be listed as hosts of this event.",
)
signed_up_users = ParentalManyToManyField(
User,
related_name="signed_up_events",
blank=True,
help_text="Users who have signed up for this event.",
)
@property
def attendees_count(self):
return self.signed_up_users.count() # pyright: ignore[reportAttributeAccessIssue]
def _user_signed_up(self, user):
if not user.is_authenticated:
return False
return self.signed_up_users.filter(id__in=[user.id]).exists() # pyright: ignore[reportAttributeAccessIssue]
def get_context(self, request):
context = super().get_context(request)
context["user_signed_up"] = self._user_signed_up(request.user)
return context
content_panels = Page.content_panels + [
FieldPanel("tags"),
NativeColorPanel("color"),
FieldPanel("image"),
FieldPanel("start"),
FieldPanel("end"),
FieldPanel("location"),
FieldPanel("max_attendees"),
FieldPanel("hosts", widget=CheckboxSelectMultiple),
FieldPanel("description"),
FieldPanel("signed_up_users", read_only=True, widget=CheckboxSelectMultiple),
]