Djangoブログに「公開・非公開」管理機能を追加する方法を解説。管理画面での制御、APIのフィルタリング、カテゴリ一覧の制限、推薦記事の調整など、既存のシステムに最小限の変更でスムーズに導入する手順を紹介します。
Django を使ったブログシステムでは、「記事を非公開にしたい」「下書きとして保存したい」 というニーズが生じることがあります。
今回は、既存のシステムに大きな変更を加えずに「公開・非公開」の選択肢を導入 する方法について解説します。
is_published
フィールドの追加まず、記事を公開するかどうかを管理する BooleanField (is_published
) を Post
モデルに追加しました。
PYTHONclass Post(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) title = models.CharField(max_length=255, verbose_name="タイトル") content = MarkdownxField(null=True, verbose_name="本文") is_pinned = models.BooleanField(default=False, verbose_name="ピン留め") # 公開・非公開を管理 is_published = models.BooleanField(default=False, verbose_name="公開する")
シンプルな is_published=True
/ False
のブール値を持たせるだけで管理が可能になります。
これにより、新たな status
フィールドを作ることなく、API や Django の admin 管理画面での実装が簡潔になりました。
新たに is_published
を追加した場合、既存の記事は「非公開」扱いになってしまいます。
そのため、マイグレーション時に既存の記事をすべて「公開済み」に設定する ことで、既存データをスムーズに移行しました。
PYTHONfrom django.db import migrations, models def set_is_published_true_for_existing_posts(apps, schema_editor): Post = apps.get_model('base', 'Post') Post.objects.all().update(is_published=True) class Migration(migrations.Migration): dependencies = [ ('base', '0011_alter_post_options_post_order'), ] operations = [ migrations.AddField( model_name='post', name='is_published', field=models.BooleanField(default=False, verbose_name='公開する'), ), migrations.RunPython(set_is_published_true_for_existing_posts, reverse_code=migrations.RunPython.noop), ]
これにより、既存のデータに影響を与えず、すべての記事を自動的に公開するように処理 ができました。
Django の管理画面から 公開・非公開を簡単に切り替えられるようにする ため、list_display
に is_published
を追加し、一覧で状態を確認できるようにしました。
PYTHON@admin.register(Post) class PostAdmin(admin.ModelAdmin): list_display = ("title", "is_published", "is_pinned", "created_at") list_filter = ("is_published", "is_pinned") search_fields = ("title", "content") ordering = ("-created_at",)
これにより、管理者が チェックボックスで「公開」状態を切り替えたり、一括変更 したりできるようになりました。
Django REST Framework (DRF) で提供している API に対し、非公開の記事を除外しました。
PYTHONclass PostListViewSet(viewsets.ReadOnlyModelViewSet): queryset = Post.objects.filter(is_published=True).order_by("-custom_id", "-date") serializer_class = PostListSerializer
この修正により、API から 「公開されている記事のみ」 を取得できるようになり、フロントエンド側で不必要なフィルタリングをする必要がなくなりました。
通常、Category
モデルはすべてのカテゴリを返しますが、「非公開記事しかないカテゴリは取得されない」 ように変更しました。
PYTHONclass CategoryViewSet(viewsets.ReadOnlyModelViewSet): queryset = Category.objects.filter(post__is_published=True).distinct() serializer_class = CategorySerializer
類似記事を提案する機能にも 「非公開の記事を除外」 するフィルタを適用しました。
PYTHON@api_view(["GET"]) def recommend_and_opposite(request, slug, mode="both", **kwargs): try: target_post = Post.objects.get(slug=slug, is_published=True) # 非公開記事は 404 except Post.DoesNotExist: return Response({"error": "Article not found or not published"}, status=404)
この修正により、非公開記事が推薦リストに表示されることなく、安全に類似記事を表示できるようになりました。
今回の対応により、以下の点がスムーズに実装できました:
is_published
フィールドで制御この方法なら、既存のブログシステムに大きな変更を加えず、スムーズに「公開・非公開」管理を導入 できます。
回 | タイトル | リンク |
---|---|---|
第 1 回 | ブログ設計図の概要 | 詳 細 |
第 2 回 | .md ファイルの取込みと JSON 化の概要 | 詳 細 |
第 3 回 | Embedding API を活用した類似記事推薦 | 詳 細 |
第 4 回 | Next.js による推薦記事 API の活用 | 詳 細 |
第 5 回 | Post モデルの設計と Markdownx の適用 | 詳 細 |
第 6 回 | Django 画像アップロード時の画像処理 | 詳 細 |
第 7 回 | Markdownx で画像をアップロード | 詳 細 |
第 8 回 | 多様な記事推薦システムの導入 | 詳 細 |
第 9 回 | 自動クラスタリング vs. 手動分類 | 詳 細 |
第 10 回 | 「公開・非公開」管理機能の実装 | この記事 |
当サイトの情報は、一般的な参考情報として提供しております。
正確な情報の掲載に努めておりますが、その内容の正確性・完全性・最新性を保証するものではありません。
記事の内容をご利用の際は、ご自身の責任において判断し、必要に応じて専門家にご相談ください。
当サイトの情報の利用により生じたいかなる損害についても、一切の責任を負いかねますのでご了承ください。
※ 本ページでは、著作権法に基づき、適正な引用の範囲内でコンテンツを紹介しています。
オリジナルの情報は発信元をご確認ください。
もし問題がありましたら、こちら からお問い合わせください。