from django.db import models import markdown from django.utils.functional import cached_property from django.template import engines from django_jinja.backend import Origin class Tag(models.Model): __yamdl__ = True slug = models.SlugField(max_length=128, primary_key=True) content = models.TextField() class Page(models.Model): __yamdl__ = True _template_cache = {} title = models.CharField(max_length=255) raw_content = models.TextField() content = models.TextField() toc = models.JSONField() slug = models.CharField(max_length=128, unique=True, db_index=True, default=None, null=True) tags = models.ManyToManyField(Tag) @classmethod def from_yaml(cls, **data): tags = data.pop("tags", None) md = markdown.Markdown(extensions=["toc"]) content = data.pop("content") data["raw_content"] = content data["content"] = md.convert(content) data["toc"] = { "html": md.toc, "tokens": md.toc_tokens } instance = cls.objects.create(**data) if tags: instance.tags.set(tags) return instance @cached_property def content_template(self): if (cached_template := self._template_cache.get(self.slug)) is None: cached_template = self._template_cache[self.slug] = engines["jinja2"].from_string(self.content) cached_template.origin = Origin(name=self.slug, template_name=self.slug) cached_template.name = self.slug return cached_template