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), ]