카테고리 없음

[Django 3일차] Django 웹 프레임워크를 활용한 URL 단축 서비스 구현 2/4 (short_url 프로젝트)(250514)

Chansman 2025. 5. 14. 13:59

📌 Django Redirect View – 단축 URL 리디렉션 기능 완전 정복


1️⃣ 라우팅과 View의 연결: 요청을 처리하는 흐름

Django에서 라우팅이란, 사용자의 요청이 어떤 View 함수로 연결될지를 결정하는 과정입니다. urls.py 파일에서 URL 패턴을 지정하고, 요청이 들어올 경우 어떤 뷰를 호출할지 지정합니다.

# config/urls.py
from django.urls import path
from shortener import views

urlpatterns = [
    path('', views.home_view, name='home'),
    path('short-urls/', views.short_url_create_view, name='shorten_url'),
    path('<str:code>/', views.redirect_view, name='shorten_url_redirect'),  # ✅ 동적 URL 처리
]
  • "<str:code>/" : 사용자에게 부여된 단축 코드 값에 따라 동적으로 URL이 리디렉트됩니다.
  • 이처럼 꺾쇠 괄호로 감싸진 변수는 동적 URL이며, View 함수로 자동 전달됩니다.

2️⃣ Redirect View: 핵심 기능 구현

이제 동적으로 들어온 단축 URL을 원래 URL로 리다이렉트하는 View 함수를 정의합니다.

# shortener/views.py
from django.shortcuts import redirect, get_object_or_404
from .models import ShortURL

# ✅ 단축 URL 요청을 원래 URL로 리디렉트
def redirect_view(request, code):
    short_url = get_object_or_404(ShortURL, code=code)
    short_url.access_count = F("access_count") + 1  # 조회수 증가 (DB 레벨)
    short_url.save()  # 반드시 save() 호출해야 DB에 반영됨
    return redirect(short_url.original_url)
  • get_object_or_404() : 해당 코드가 없을 경우 자동으로 404 에러 반환
  • F("access_count") + 1 : 동시 접근 시 Race Condition 방지를 위한 Django ORM 기능
  • redirect(...) : 응답을 해당 URL로 보내 브라우저가 새로 이동하게 함

주의할 점: .access_count += 1 처럼 파이썬 값 자체를 증가시키면 동시 요청에서 값 꼬임이 발생할 수 있습니다.


3️⃣ 폼을 활용한 데이터 처리: 생성 및 유효성 검사

# shortener/views.py
from .forms import ShortURLForm

# ✅ 단축 URL 생성 처리
def short_url_create_view(request):
    if request.method == "POST":
        form = ShortURLForm(request.POST)
        if form.is_valid():
            short_url = form.save(commit=False)
            short_url.generate_code()  # 랜덤 코드 생성
            short_url.save()
            return redirect("home")
    return redirect("home")
  • ShortURLForm : 사용자가 입력한 원본 URL을 받아 모델 인스턴스를 생성하는 모델폼
  • generate_code() : 8자리 랜덤 문자열 생성 (모델 메서드로 정의 필요)
  • commit=False : 저장을 잠시 보류하고 중간 처리 후 저장

4️⃣ 데이터 모델 구성

# shortener/models.py
from django.db import models
from django.utils.crypto import get_random_string

class ShortURL(models.Model):
    original_url = models.URLField()
    code = models.CharField(max_length=8, unique=True)
    access_count = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

    def generate_code(self):
        self.code = get_random_string(8)
  • access_count : 몇 번 클릭되었는지를 추적
  • generate_code() : 무작위 코드 생성으로 고유한 단축 URL 생성

5️⃣ 에러 처리: 존재하지 않는 코드 요청 시

  • get_object_or_404()를 사용하면 요청한 단축 코드가 존재하지 않을 때 자동으로 404 응답을 반환합니다.
short_url = get_object_or_404(ShortURL, code=code)
  • 브라우저 개발자 도구에서 상태코드 404를 확인할 수 있습니다.
  • 사용자에게 친절한 메시지를 제공하고 싶다면 404.html을 만들어 예쁜 화면으로 대체 가능합니다.

6️⃣ 💡 최종 흐름 요약 (시각적 순서)

[사용자 입력]
   ⬇️ original_url 입력
[POST 요청 발생]
   ⬇️ short_url_create_view → DB 저장
[Redirect to home]
   ⬇️ home_view → 생성된 단축 링크 목록 출력
[단축 URL 클릭]
   ⬇️ redirect_view(code)
   ⬇️ DB 조회 및 access_count 증가
   ⬇️ original_url로 이동

7️⃣ 🔒 고급 팁과 보안 고려

  • Race Condition 방지: F("access_count") + 1로 DB 연산 처리
  • 오류 방지: get_object_or_404()로 존재하지 않는 코드 요청 시 404 반환
  • 코드 중복 방지: generate_code()는 고유 값 생성 시 중복 검사 로직 추가 고려
  • CSRF 보호: Form 제출 시 {% csrf_token %} 포함 필수

이처럼 Django에서는 단축 URL을 처리하는 과정을 뷰 함수 → 라우팅 → 모델 → 응답으로 체계적으로 구현할 수 있습니다.
리디렉션 기능은 실무에서도 자주 사용되며, 기능은 단순하지만 구현 과정에서 데이터 처리, 오류 방지, 보안 요소를 함께 고려해야 합니다.

👉 다음에는 QR 코드 생성이나 만료 기간 설정 기능도 함께 확장해볼 수 있어요!