장고에서 슬러그(Slug) 자동 생성하기 (관리자 페이지 활용, UUID 중복 처리 등)

소요 시간: 5분

Django로 웹 애플리케이션을 개발하다 보면, 슬러그(Slug)를 자동으로 생성해야 하는 상황이 자주 발생한다. 슬러그는 URL에서 자주 사용되는 짧고 고유한 문자열로, 보통 제목 등을 기반으로 생성된다.

이번 글에서는 Django 관리자 페이지에서 데이터 생성 시 슬러그를 자동으로 생성하는 방법과 함께, UUID를 사용한 고유 슬러그 생성 및 중복 처리까지 다뤄보겠다.


1. 슬러그란 무엇인가?

슬러그(Slug)는 사람이 읽기 쉽고 검색엔진 최적화(SEO)에 도움이 되는 문자열이다. 보통 URL의 일부로 사용되며, 예를 들어 다음과 같은 형태로 작성된다:

https://example.com/blog/this-is-a-sample-post

위 URL에서 this-is-a-sample-post가 슬러그다. 슬러그는 다음과 같은 특징을 가진다:


2. Django에서 슬러그 자동 생성하기

Django에서는 모델의 save() 메서드를 오버라이드하여 데이터를 저장하기 전에 슬러그를 자동으로 생성할 수 있습니다.

from django.db import models
from django.utils.text import slugify

class MyModel(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True, blank=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            # 제목 기반으로 슬러그 생성
            base_slug = slugify(self.title)
            unique_slug = base_slug
            num = 1
            # 중복 슬러그 방지
            while MyModel.objects.filter(slug=unique_slug).exists():
                unique_slug = f"{base_slug}-{num}"
                num += 1
            self.slug = unique_slug
        super().save(*args, **kwargs)

slugify는 문자열을 슬러그 형식으로 변환한다.

slug 필드는 unique=True로 설정해서 데이터베이스에서 고유성을 강제한다. 그래서 슬러그가 이미 존재하면 번호를 추가하여 고유하게 만들었다.


3. 관리자 페이지에서 슬러그 필드 숨기기

슬러그는 자동으로 생성되므로, Django 관리자 페이지에서 사용자가 직접 입력하지 못하도록 숨기는 것이 좋다.

from django.contrib import admin
from .models import MyModel

class MyModelAdmin(admin.ModelAdmin):
    exclude = ('slug',)  # 슬러그 필드를 숨김
    list_display = ('title', 'slug')  # 슬러그를 리스트에 표시

admin.site.register(MyModel, MyModelAdmin)


4. UUID를 사용한 고유 슬러그 생성

UUID(Universally Unique Identifier)는 고유한 식별자를 생성하는 표준이다. 슬러그를 제목 기반으로 생성하면 중복 검사를 해야 하지만, UUID를 사용하면 사실상 중복을 걱정하지 않아도 된다.

import uuid

class MyModel(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True, blank=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = str(uuid.uuid4())[:8]  # 8자리 UUID 슬러그
        super().save(*args, **kwargs)

UUID 중복 문제는 없을까? UUID는 이론적으로 중복될 가능성이 있지만, 중복 확률은 극도로 낮아 실제 애플리케이션에서는 추가 검사를 하지 않아도 충분히 안전하다. 하지만, 데이터베이스에서 중복을 확인하려면 다음과 같은 로직을 추가할 수 있다:

def save(self, *args, **kwargs):
    if not self.slug:
        while True:
            new_slug = str(uuid.uuid4())[:8]
            if not MyModel.objects.filter(slug=new_slug).exists():
                self.slug = new_slug
                break
    super().save(*args, **kwargs)

이 코드는 데이터베이스에서 슬러그의 중복 여부를 확인한 후 고유한 값이 생성될 때까지 반복합니다.


5. pre_save 신호로 슬러그 생성하기

Django의 신호(Signals)를 활용하면 모델의 save() 메서드를 수정하지 않고도 슬러그를 자동 생성할 수 있다.

from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.text import slugify
from .models import MyModel

@receiver(pre_save, sender=MyModel)
def create_slug(sender, instance, **kwargs):
    if not instance.slug:
        base_slug = slugify(instance.title)
        unique_slug = base_slug
        num = 1
        while sender.objects.filter(slug=unique_slug).exists():
            unique_slug = f"{base_slug}-{num}"
            num += 1
        instance.slug = unique_slug


6. 결론: 적합한 슬러그 생성 방법 선택

Django에서 슬러그를 자동으로 생성하는 방법은 다양하다. 프로젝트의 요구 사항에 따라 적합한 방법을 선택한다:

Django를 활용한 슬러그 자동 생성은 URL 구조 최적화와 사용자 경험 개선은 물론, SEO에도 긍정적인 영향을 줄 수 있다.


관련 글

장고 리스트