Phase 1: T-101/T-102/T-103 内容模型 + 17 tests. T-104 BLOCKED 待种子数据
This commit is contained in:
+265
-1
@@ -1,3 +1,267 @@
|
||||
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
|
||||
|
||||
# Create your models here.
|
||||
|
||||
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"
|
||||
|
||||
Reference in New Issue
Block a user