from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator from modelcluster.fields import ParentalManyToManyField from wagtail.models import Page from wagtail.admin.panels import FieldPanel, MultiFieldPanel from wagtail.fields import RichTextField from wagtail.snippets.models import register_snippet class ScenarioIndexPage(Page): parent_page_types = ["home.HomePage"] subpage_types = ["core.ScenarioPage"] max_count = 1 content_panels = Page.content_panels class Meta: verbose_name = "Scenario Index" class ScenarioPage(Page): parent_page_types = ["core.ScenarioIndexPage"] subpage_types = [] content_panels = Page.content_panels class Meta: verbose_name = "Scenario" @register_snippet class Language(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(max_length=50, unique=True) panels = [ FieldPanel("name"), FieldPanel("slug"), ] class Meta: ordering = ["name"] verbose_name = "Language" verbose_name_plural = "Languages" def __str__(self): return self.name @register_snippet class Framework(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(max_length=50, unique=True) panels = [ FieldPanel("name"), FieldPanel("slug"), ] class Meta: ordering = ["name"] verbose_name = "Framework" verbose_name_plural = "Frameworks" def __str__(self): return self.name @register_snippet class DatabaseOption(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(max_length=50, unique=True) panels = [ FieldPanel("name"), FieldPanel("slug"), ] class Meta: ordering = ["name"] verbose_name = "Database Option" verbose_name_plural = "Database Options" def __str__(self): return self.name @register_snippet class SkeletonFeature(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(max_length=50, unique=True) panels = [ FieldPanel("name"), FieldPanel("slug"), ] class Meta: ordering = ["name"] verbose_name = "Skeleton Feature" verbose_name_plural = "Skeleton Features" def __str__(self): return self.name class ProjectIndexPage(Page): parent_page_types = ["home.HomePage"] subpage_types = ["core.SkeletonProjectPage"] max_count = 1 content_panels = Page.content_panels class Meta: verbose_name = "Project Index" class SkeletonProjectPage(Page): MATURITY_CHOICES = [ ("experimental", "Experimental"), ("stable", "Stable"), ("mature", "Mature"), ] MAINTENANCE_CHOICES = [ ("active", "Active"), ("slow", "Slow"), ("unknown", "Unknown"), ("archived", "Archived"), ] summary = models.TextField() github_url = models.URLField() official_url = models.URLField(blank=True) license_name = models.CharField(max_length=100, blank=True) scenarios = ParentalManyToManyField("core.ScenarioPage", blank=False) languages = ParentalManyToManyField("core.Language", blank=False) frameworks = ParentalManyToManyField("core.Framework", blank=True) databases = ParentalManyToManyField("core.DatabaseOption", blank=True) features = ParentalManyToManyField("core.SkeletonFeature", blank=True) maturity = models.CharField(max_length=20, choices=MATURITY_CHOICES) maintenance_status = models.CharField( max_length=20, choices=MAINTENANCE_CHOICES, default="unknown" ) structure_score = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(5)] ) docs_score = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(5)] ) tests_score = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(5)] ) example_score = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(5)] ) dependency_score = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(5)] ) incremental_score = models.IntegerField( validators=[MinValueValidator(0), MaxValueValidator(5)] ) recommended_for = RichTextField() not_recommended_for = RichTextField(blank=True) review_notes = RichTextField(blank=True) is_featured = models.BooleanField(default=False) is_sponsored = models.BooleanField(default=False) parent_page_types = ["core.ProjectIndexPage"] subpage_types = [] @property def total_score(self): return ( self.structure_score + self.docs_score + self.tests_score + self.example_score + self.dependency_score + self.incremental_score ) content_panels = Page.content_panels + [ MultiFieldPanel( [ FieldPanel("summary"), FieldPanel("github_url"), FieldPanel("official_url"), FieldPanel("license_name"), ], heading="Basic Info", ), MultiFieldPanel( [ FieldPanel("scenarios"), FieldPanel("languages"), FieldPanel("frameworks"), FieldPanel("databases"), FieldPanel("features"), FieldPanel("maturity"), FieldPanel("maintenance_status"), ], heading="Classification", ), MultiFieldPanel( [ FieldPanel("structure_score"), FieldPanel("docs_score"), FieldPanel("tests_score"), FieldPanel("example_score"), FieldPanel("dependency_score"), FieldPanel("incremental_score"), ], heading="Scores", ), MultiFieldPanel( [ FieldPanel("recommended_for"), FieldPanel("not_recommended_for"), FieldPanel("review_notes"), ], heading="Review Content", ), MultiFieldPanel( [ FieldPanel("is_featured"), FieldPanel("is_sponsored"), ], heading="Display Options", ), ] class Meta: verbose_name = "Skeleton Project" class ArticleIndexPage(Page): parent_page_types = ["home.HomePage"] subpage_types = ["core.ArticlePage"] max_count = 1 content_panels = Page.content_panels class Meta: verbose_name = "Article Index" class ArticlePage(Page): body = RichTextField() related_projects = ParentalManyToManyField( "core.SkeletonProjectPage", blank=True ) parent_page_types = ["core.ArticleIndexPage"] subpage_types = [] content_panels = Page.content_panels + [ FieldPanel("body"), FieldPanel("related_projects"), ] class Meta: verbose_name = "Article"