はじめに

当サイト Nicoyou Games は Django で構築しており、自作のゲームやツールなどを公開しています。しかし、これまでは 1 ページ 1 ページすべて HTML で作成していたため、ちょっとした開発進捗や個人的な情報を気軽に発信する手段がありませんでした。

そこで、管理ページからテキストを登録するだけで新しいページを作成できるブログ機能を実装しました。この記事はそのテストも兼ねた記念すべき初投稿です。

まだブログとしては最低限の状態ですが、今後はコメント機能や返信機能なども少しずつ追加していく予定です。

当サイトのブログ設計について

Django に blog アプリケーションを追加し、メインは以下の 2 つのモデルで管理しています。

ブログに付与するタグモデル

同じ分野のブログを紐づけ、類似した情報を探しやすくするためです。

class Tag(models.Model):
    id = models.SlugField("タグ ID", max_length=32, primary_key=True)
    name = models.CharField("タグ 名", max_length=32)
    created_at = models.DateTimeField("作成日時", auto_now_add=True, blank=True)
    updated_at = models.DateTimeField("更新日時", auto_now=True, blank=True)

    def __str__(self):
        return self.name

    class Meta():
        verbose_name = "タグ"
        verbose_name_plural = "タグ"

ブログ記事本体のモデル

ブログ自体の情報を保持します。

サムネイルは同一のものを使い回すことが多いため、アップロードのたびに異なる名前を付けるのではなく、画像のハッシュ値をファイル名にしています。これにより、同じ画像が指定された場合は既存のファイルをそのまま使用します。

また、ユニークキーが冗長にはなりますが、SEO 対策のため URL に ID をそのまま使うようなことはせず、URL を毎回自分で命名できるようにしています。

デフォルトの整数ユニークキーを消さない理由は、文字列をインデックスにすると DB からの検索が遅くなるためです。

class Article(models.Model):
    page_name = models.SlugField("URL", max_length=32, unique=True)
    thumbnail = models.FileField("サムネイル", upload_to=thumbnail_upload_to, storage=server.OverwriteStorage, null=True, blank=True)
    title = models.CharField("タイトル", max_length=64)
    text = models.TextField("本文")
    tags = models.ManyToManyField(Tag, verbose_name="タグ", blank=True)
    is_published = models.BooleanField("公開", default=True)
    created_by = models.ForeignKey(get_user_model(), db_column="created_by", on_delete=models.SET_NULL, null=True, related_name="create_article", verbose_name="作成者")
    updated_by = models.ForeignKey(get_user_model(), db_column="updated_by", on_delete=models.SET_NULL, null=True, related_name="update_article", verbose_name="最終更新者")
    created_at = models.DateTimeField("作成日時", auto_now_add=True, blank=True)
    updated_at = models.DateTimeField("更新日時", auto_now=True, blank=True)

    def __str__(self) -> str:
        return self.title

    class Meta():
        verbose_name = "記事"
        verbose_name_plural = "記事"

最後に

view では Article モデルに格納された HTML にシンタックスハイライトなどのデザインを適用し、タグをもとに記事一覧や関連記事を表示しています。

今後は Django に関する技術記事や、日常のちょっとした話題なども少しずつ書いていきたいと思っています。