Files
skelet/core/models.py
T

268 lines
7.1 KiB
Python
Raw Normal View History

2026-07-06 17:30:34 +08:00
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
2026-07-06 17:30:34 +08:00
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"