Djangoでスラッグ(slug)を設定する

この記事ではDjangoでスラッグを設定する手順を紹介します。
スラッグとは、URL(パーマリンク)の末尾の部分を任意の文字列に指定できる機能です。
たとえばWordPressでは「パーマリンク」を設定できる箇所があります。

DjangoでもWordPressのようにパーマリンクを設定することができますので、その方法を紹介していきます。

Djangoプロジェクトを作成

% mkdir slugexample; cd slugexample
% pipenv install django==3.0.4
% pipenv shell
% django-admin startproject slugexample .
% python manage.py startapp slugapp

上記の作業の詳細は以下の記事を参考にしてください。

DjangoでView(ビュー)を作成して表示する

ここまでの作業で、以下のようなファイルやフォルダができます。

% tree .
.
├── Pipfile
├── Pipfile.lock
├── manage.py
├── slugapp
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
└── slugexample
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Djangoプロジェクトにアプリをインストールする

slugexample/settings.pyのINSTALLED_APPSに先ほど作成したslugappの設定ファイルを追加します。

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'slugapp.apps.SlugappConfig', # new
]

モデルを追加する

slugapp/models.pyにモデルを追加します。

from django.db import models
from django.urls import reverse

# Create your models here.
class Post(models.Model):
  title = models.CharField(max_length=200)
  body = models.TextField()
  slug = models.SlugField(null=False, unique=True)

  def __str__(self):
    return self.title

  def get_absolute_url(self):
    return reverse('post_detail', kwargs={'slug': self.slug})

モデル作成後はマイグレーションを行います。

% python manage.py makemigrations slugapp
% python manage.py migrate

管理者ユーザーからデータを登録する

管理者ユーザーを作って、データベースに直接データを入力します。
ここで入力したデータを表示させます。

% python manage.py createsuperuser

slugapp/admin.pyを編集します。

from django.contrib import admin

from .models import Post  # new

# Register your models here.
class PostAdmin(admin.ModelAdmin):
  list_display = ('title', 'body', 'slug')

admin.site.register(Post, PostAdmin)

サーバーを起動して、http://127.0.0.1:8000/admin/login/?next=/admin/を開きます。

% python manage.py runserver

以下の管理者ページの「Add」をクリックして、新しいデータを追加します。

追加するデータは以下です。

Title Abe Hiroshi
Body ローマ人
Slug abehiroshi-roma

URLを設定する

プロジェクトレベルの設定ファイルslugexample/urls.pyにアプリ用のurls.pyを読み込ませるように設定を入れます。

from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('slugapp.urls'))
]

次にslugapp/urls.pyを作成します。
slugapp/urls.pyには以下のように書いてください。

from django.urls import path

from .views import PostListView, PostDetailView

urlpatterns = [
  path('<slug:slug>', PostDetailView.as_view(), name='post_detail'),
  path('', PostListView.as_view(), name='post_list'),
]

ビューを作成する

slugapp/views.pyに以下のように書きます。

from django.shortcuts import render
from django.views.generic import ListView, DetailView

from .models import Post

# Create your views here.

class PostListView(ListView):
  model = Post
  template_name = 'post_list.html'

class PostDetailView(DetailView):
  model = Post
  template_name = 'post_detail.html'

テンプレートを作成する

プロジェクトのルートディレクトリに「templates」というディレクトリを作成します。
templatesの下に「post_detail.html」と「post_lis.html」を作成してください。

ディレクトリ構成はこうなります。

slugexample/settings.pyのTEMPLATESを以下のように編集します。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')], # new
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

テンプレートの使い方は以下の記事を参考にしてください。
DjangoでTemplates(テンプレート)を作成してHTMLを表示する

ここで% python manage.py runserverを実行します。
すると、以下のような一覧が表示されます(ListViewの機能です)

リンクをクリックすると、以下のような画面が表示されます。

URLはhttp://127.0.0.1:8000/abehiroshi-romaとなっています。

パーマリンクの設定ができるようになりました。

参考 Django Slug TutorialLearnDjango

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です