Django の Slug フィールドを徹底解説! validate_slug 関数の使い方からサンプルコードまで


Slug フィールドは、URL やファイル名などの識別子として使用される短いテキスト文字列です。この関数は、Slug フィールドの値が以下の条件を満たしているかどうかを確認します。

  • ハイフン (-) で終わっていない。
  • 空白文字を含まない。
  • 英数字、アンダースコア (_)、ハイフン (-) のみで構成されている。

validate_slug 関数は、RegexValidator クラスを使用して実装されています。RegexValidator クラスは、正規表現を使用して値を検証する validator です。validate_slug 関数で使用される正規表現は以下の通りです。

r"^[-a-zA-Z0-9_]+\Z"

この正規表現は、以下の条件を満たす文字列に一致します。

  • ハイフン (-) で終わっていない。
  • 空白文字を含まない。
  • 英数字、アンダースコア (_)、ハイフン (-) のみで構成されている。

validate_slug 関数は、値が有効な場合に None を返し、値が無効な場合は ValidationError 例外を発生させます。

from django.core.validators import validate_slug

try:
  validate_slug("this-is-a-valid-slug")
except ValidationError as e:
  print(e)

このコードは、"this-is-a-valid-slug" という文字列が有効な Slug であることを検証します。この文字列は上記の条件を満たしているため、validate_slug 関数は None を返します。

from django.core.validators import validate_slug

try:
  validate_slug("this-is-an-invalid-slug-")
except ValidationError as e:
  print(e)

このコードは、"this-is-an-invalid-slug-" という文字列が有効な Slug であるかどうかを検証します。この文字列は最後の文字がハイフン (-) であるため、validate_slug 関数は ValidationError 例外を発生させます。

django.core.validators.validate_slug 関数は、Slug フィールドの値が有効かどうか検証するために使用されます。この関数は、正規表現を使用して値が英数字、アンダースコア (_)、ハイフン (-) のみで構成されているかどうか、空白文字を含まないかどうか、ハイフン (-) で終わっていないかどうかを確認します。



from django.db import models
from django.core.validators import validate_slug

class MyModel(models.Model):
  title = models.CharField(max_length=255)
  slug = models.SlugField(max_length=255, unique=True, validators=[validate_slug])

このコードは、MyModel というモデルを定義します。このモデルには、title フィールドと slug フィールドがあります。title フィールドは、モデルのタイトルを格納するテキストフィールドです。slug フィールドは、URL やファイル名などの識別子として使用される短いテキスト文字列を格納する Slug フィールドです。validators 引数を使用して、validate_slug 関数を slug フィールドの validator として追加しています。

フォーム定義

from django import forms
from .models import MyModel

class MyModelForm(forms.ModelForm):
  class Meta:
    model = MyModel
    fields = ['title', 'slug']

このコードは、MyModelForm というフォームを定義します。このフォームは、MyModel モデルの title フィールドと slug フィールドに対応しています。

ビュー定義

from django.shortcuts import render
from .models import MyModel
from .forms import MyModelForm

def my_view(request):
  if request.method == 'POST':
    form = MyModelForm(request.POST)
    if form.is_valid():
      form.save()
      return redirect('my_view')
  else:
    form = MyModelForm()

  return render(request, 'my_view.html', {'form': form})

このコードは、my_view というビューを定義します。このビューは、MyModelForm フォームを表示し、送信されたデータを処理します。

テンプレート

{% extends 'base.html' %}

{% block content %}
  <h1>My Model</h1>

  <form method="post">
    {% csrf_token %}
    {{ form }}
    <button type="submit">Submit</button>
  </form>
{% endblock %}

このテンプレートは、MyModelForm フォームを表示します。

実行

このコードを実行すると、ユーザーは title フィールドと slug フィールドを入力して、MyModel モデルの新しいインスタンスを作成できます。slug フィールドの値は validate_slug 関数によって検証されます。

  • validate_slug 関数は、デフォルトで英数字、アンダースコア (_)、ハイフン (-) のみで構成された文字列を許可します。許可される文字セットを変更するには、allow_unicode 引数を使用できます。
  • validate_slug 関数は、値が有効な場合に None を返しますが、値が無効な場合は ValidationError 例外を発生させます。エラー処理を行う場合は、この例外を捕捉する必要があります。
  • validate_slug 関数は、Slug フィールドの値を検証するためにのみ使用できます。他の種類のフィールドの値を検証するには、別の validator を使用する必要があります。


カスタム validator を作成する

validate_slug 関数は、RegexValidator クラスを使用して実装されています。RegexValidator クラスを使用して、独自の正規表現に基づいて値を検証するカスタム validator を作成できます。

from django.core.validators import RegexValidator
from django.utils.translation import gettext_lazy

def validate_my_slug(value):
  """
  My custom slug validator.
  """
  error_message = gettext_lazy('Enter a valid slug. This value may contain '
                             'letters, numbers, underscores, or hyphens, but cannot '
                             'start or end with a hyphen.')
  validator = RegexValidator(
      regex=r'^[-a-zA-Z0-9_]+\Z',
      error=error_message,
  )
  return validator(value)

このコードは、validate_my_slug というカスタム validator を作成します。この validator は、次の条件を満たす文字列に一致します。

  • ハイフン (-) で終わっていない。
  • 空白文字を含まない。
  • 英数字、アンダースコア (_)、ハイフン (-) のみで構成されている。

この validator を使用するには、validators 引数を使用してモデルの SlugField に追加します。

from django.db import models

class MyModel(models.Model):
  title = models.CharField(max_length=255)
  slug = models.SlugField(max_length=255, unique=True, validators=[validate_my_slug])

サードパーティ製のライブラリを使用する

Slug フィールドの値を検証するために使用できるサードパーティ製のライブラリがいくつかあります。

これらのライブラリは、独自の要件に合ったカスタム Slug 生成ロジックを実装する場合に役立ちます。

手動で検証する

Slug フィールドの値を手動で検証することもできます。これは、シンプルな要件がある場合に役立ちます。

def clean_slug(self):
  """
  Validate the slug field.
  """
  value = super().clean_slug()

  if not value.isalnum():
    raise ValidationError('Slug must contain only letters and numbers.')

  if value.startswith('-') or value.endswith('-'):
    raise ValidationError('Slug cannot start or end with a hyphen.')

  return value

このコードは、MyModel モデルの clean_slug メソッドを定義します。このメソッドは、slug フィールドの値が有効かどうかを確認します。

django.core.validators.validate_slug 関数は、Slug フィールドの値を検証するための便利なツールですが、他の方法もあります。要件に応じて、カスタム validator、サードパーティ製のライブラリ、または手動検証を使用することを検討してください。

  • Slug フィールドの値を検証する際には、国際化を考慮する必要があります。validate_slug 関数は、デフォルトで英数字、アンダースコア (_)、ハイフン (-) のみで構成された文字列を許可します。許可される文字セットを変更するには、allow_unicode 引数を使用できます。
  • Slug フィールドの値を検証する際には、パフォーマンスを考慮する必要があります。validate_slug 関数は、正規表現を使用して値を検証するため、比較的処理速度が遅くなります。パフォーマンスが重要な場合は、カスタム validator またはサードパーティ製のライブラリを使用して、より効率的な検証ロジックを実装することを検討してください。