Django 2.0でブログアプリケーションを作成する実践例

1. Djangoのインストール方法

DjangoはPythonのウェブフレームワークです。Python 3.4以上が必要です。Python 3.6.5が推奨されています。

  • Pythonのインストール確認方法:
    $ python --version
    
  • virtualenvを使用して開発環境を作成:
    $ pip install virtualenv
    $ virtualenv my_env
    $ source my_env/bin/activate
    
  • Djangoのインストール方法:
    $ pip install Django==2.0.5
    

2. ブログプロジェクトの作成

Djangoプロジェクトを作成します。

$ django-admin startproject my_blog

以下のディレクトリ構造が作成されます。

my_blog/
  manage.py
  my_blog/
    __init__.py
    settings.py
    urls.py
    wsgi.py

3. ブログアプリケーションの作成

プロジェクト内にブログアプリケーションを作成します。

$ python manage.py startapp my_blog_app

作成されたディレクトリ構造は以下のとおりです。

my_blog_app/
  __init__.py
  admin.py
  models.py
  tests.py
  views.py

4. データベースモデルの作成

ブログの記事を表すモデルを作成します。

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User

class BlogPost(models.Model):
    STATUS_CHOICES = (
        ('draft', '下書き'),
        ('published', '公開')
    )
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250, unique_for_date='publish')
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='my_blog_posts')
    body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')

    class Meta:
        ordering = ('-publish',)

    def __str__(self):
        return self.title

5. モデルのマイグレーション

モデルをデータベースに反映します。

$ python manage.py makemigrations my_blog_app
$ python manage.py migrate

6. 管理サイトの設定

管理サイトにアクセスするためのスーパーユーザーを作成します。

$ python manage.py createsuperuser

作成後は以下URLにアクセスします。

http://localhost:8000/admin/

7. ブログアプリケーションのビュー作成

ブログ記事の一覧と詳細を表示するビューを作成します。

from django.shortcuts import render, get_object_or_404
from .models import BlogPost

def blog_post_list(request):
    posts = BlogPost.objects.filter(status='published').order_by('-publish')
    return render(request, 'my_blog_app/blog_post_list.html', {'posts': posts})

def blog_post_detail(request, year, month, day, slug):
    post = get_object_or_404(BlogPost, slug=slug, publish__year=year, publish__month=month, publish__day=day)
    return render(request, 'my_blog_app/blog_post_detail.html', {'post': post})

8. URLルーティングの設定

アプリケーション内のURLルーティングを設定します。

from django.urls import path
from . import views

urlpatterns = [
    path('', views.blog_post_list, name='blog_post_list'),
    path('////', views.blog_post_detail, name='blog_post_detail'),
]

9. テンプレートの作成

以下テンプレートを作成します。

blog_post_list.html:

{% extends 'base.html' %}
{% block content %}
    <h1>ブログ記事一覧</h1>
    {% for post in posts %}
        <div class="post">
            <h2><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h2>
            <p class="date">公開日: {{ post.publish }}</p>
            <p class="author">著者: {{ post.author }}</p>
            <p class="body">{{ post.body|truncatewords:30|linebreaks }}</p>
        </div>
    {% endfor %}
{% endblock %}

blog_post_detail.html:

{% extends 'base.html' %}
{% block content %}
    <h1>{{ post.title }}</h1>
    <div class="date">公開日: {{ post.publish }}</div>
    <div class="author">著者: {{ post.author }}</div>
    <div class="body">{{ post.body|linebreaks }}</div>
{% endblock %}

10. ページネーションの追加

ブログ記事の一覧ページにページネーションを追加します。

ビューの修正例:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def blog_post_list(request):
    posts = BlogPost.objects.filter(status='published').order_by('-publish')
    paginator = Paginator(posts, 3)  # 1ページあたり3件表示
    page = request.GET.get('page')
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    return render(request, 'my_blog_app/blog_post_list.html', {'posts': posts})

ページネーション用テンプレート:

{% if posts.has_previous %}
    <a href="?page={{ posts.previous_page_number }}">前ページ</a>
{% endif %}
<span>現在 {{ posts.number }} / {{ posts.paginator.num_pages }} ページ</span>
{% if posts.has_next %}
    <a href="?page={{ posts.next_page_number }}">次ページ</a>
{% endif %}

11. クラスベースビューの使用

クラスベースビューを使用してブログ記事一覧を表示します。

from django.views.generic import ListView

class BlogPostListView(ListView):
    model = BlogPost
    context_object_name = 'posts'
    paginate_by = 3
    template_name = 'my_blog_app/blog_post_list.html'

URLルーティングの修正例:

from django.urls import path
from .views import BlogPostListView

urlpatterns = [
    path('', BlogPostListView.as_view(), name='blog_post_list'),
]

タグ: Django ORM モデル ビュー ページネーション

7月1日 23:08 投稿