💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    06 회원가입 기능 구현 (UserCreationForm + Tailwind 기반) | ✅ 편저: 코담 운영자

    6강 - 회원가입 기능 구현 (UserCreationForm + Tailwind 기반)

    form 사용


    ✨ 이번 강의 목표

    이 강의에서는 Django의 UserCreationForm을 확장하여 사용자 정의 회원가입 기능을 구현합니다. 기본 폼 구성 외에도 Tailwind CSS를 활용한 사용자 친화적인 입력 UI 구성과 함께, 실제 서비스에서 사용하는 비밀번호 검증, 자동 로그인 등의 흐름까지 다룹니다.

    • Django UserCreationForm 기반 사용자 정의 회원가입 폼 구현
    • password1, password2를 이용한 비밀번호 검증 처리
    • 위젯을 활용한 Tailwind CSS 스타일링 적용
    • 자동 로그인 및 리다이렉트 흐름 구현

    📌 1. 회원가입 흐름 요약

    회원가입의 전반적인 흐름을 이해하면 이후 구현 작업이 훨씬 수월해집니다. Django는 폼 처리, 검증, 저장, 로그인까지의 전체 과정을 구조화된 방식으로 처리할 수 있도록 도와줍니다.

    1. 사용자가 회원가입 페이지 접속
    2. 이메일, 이름, 아이디, 비밀번호, 프로필 정보 입력
    3. 서버에서 폼 유효성 검증
    4. DB에 사용자 저장
    5. 자동 로그인 후 posts:index로 리다이렉트

    🧾 2. 사용자 정의 회원가입 폼 구현

    Django의 UserCreationForm을 상속하면 기본적으로 비밀번호 필드가 포함되어 있으며, 이를 기반으로 사용자 모델의 커스텀 필드를 함께 처리할 수 있습니다. 이 예제에서는 Tailwind CSS와 함께 폼의 스타일을 지정하고, clean() 메서드를 통해 비밀번호 일치 검증까지 수행합니다.

    users/forms.py

    from django import forms as django_forms
    from django.contrib.auth.forms import UserCreationForm
    from .models import User
    
    class SignUpForm(UserCreationForm):
        class Meta:
            model = User
    
            classStyle = """w-full p-3 border border-gray-300 rounded-lg text-sm \
                            focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"""
    
            fileInputStyle=""" file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold \
                            file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 cursor-pointer """
    
            fields = (
                "email", "name", "username", "profile_photo", "website",
                "bio", "gender", "password1", "password2"
            )
    
            widgets = {
                'email': django_forms.EmailInput(attrs={'required': 'required', 'class': classStyle}),
                'name': django_forms.TextInput(attrs={'required': 'required', 'class': classStyle}),
                'username': django_forms.TextInput(attrs={'required': 'required', 'class': classStyle}),
                'profile_photo': django_forms.ClearableFileInput(attrs={'class': classStyle + fileInputStyle }),
                'website': django_forms.URLInput(attrs={'class': classStyle}),
                'bio': django_forms.Textarea(attrs={'class': classStyle}),
                'gender': django_forms.Select(attrs={'class': classStyle, 'required': 'required'}),
            }
    
            labels = {
                'email': '이메일',
                'name': '성명',
                'username': '사용자이름(아이디)',
                'profile_photo': '프로필 사진',
                'website': '웹사이트',
                'bio': '소개',
                'gender': '성별',
                'password1': '비밀번호',
                'password2': '비밀번호 확인',
            }
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['password1'].widget.attrs.update({'class': self.Meta.classStyle, 'required': 'required'})
            self.fields['password2'].widget.attrs.update({'class': self.Meta.classStyle, 'required': 'required'})
    
        def clean(self):
            cleaned_data = super().clean()
            password1 = cleaned_data.get("password1")
            password2 = cleaned_data.get("password2")
    
            if password1 != password2:
                raise django_forms.ValidationError("비밀번호가 일치하지 않습니다.")
    
            return cleaned_data
    

    UserCreationForm을 기반으로 Tailwind 스타일, 커스터마이징, password 확인 처리까지 반영된 실제 회원가입 폼입니다.


    🌐 3. URL 설정

    users/urls.py

    from django.urls import path
    from . import views
    
    app_name = "users"
    
    urlpatterns = [
        path('', views.main, name="main"),
        path('signup/', views.signup, name="signup"),
    ]
    

    🧭 4. 회원가입 뷰 구현

    뷰(View)는 사용자의 요청을 처리하고, 폼 데이터를 검증 및 저장한 뒤 결과에 따라 적절한 응답을 반환합니다. 이 과정에서 form.save(commit=False)는 DB에 저장 전 사용자 객체를 반환하고, set_password()를 호출하여 비밀번호를 안전하게 해시 처리합니다. 이후 authenticate()로 인증하고 login()을 호출하여 자동 로그인까지 처리합니다.

    users/views.py

    from django.shortcuts import render
    from django.urls import reverse
    from django.contrib.auth import authenticate, login
    from django.http import HttpResponseRedirect
    from .forms import SignUpForm
    
    def signup(request):
        if request.method == "GET":
            form = SignUpForm()
            return render(request, 'users/signup.html', {'form': form})
    
        elif request.method == "POST":
            form = SignUpForm(request.POST, request.FILES)
            if form.is_valid():
                user = form.save(commit=False)
                user.set_password(form.cleaned_data['password1'])
                user.save()
    
                username = form.cleaned_data['username']
                password = form.cleaned_data['password1']
                user = authenticate(request, username=username, password=password)
                if user is not None:
                    login(request, user)
                    return HttpResponseRedirect(reverse('posts:index'))
    
            return render(request, 'users/signup.html', {'form': form})
    

    🖼️ 5. 회원가입 템플릿 (Tailwind 적용)

    templates/users/signup.html

    <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
    
    <div class="w-full flex flex-col items-center justify-center min-h-screen bg-gray-100">
      <div class="w-full bg-white p-8 rounded-lg shadow-md max-w-lg md:max-w-2xl text-center">
        <h1 class="text-2xl font-bold text-gray-800 mb-6">회원가입</h1>
    
        <form action="{% url 'users:signup' %}" method="post" class="space-y-4" enctype="multipart/form-data">
          {% csrf_token %}
          {% for field in form %}
            <div class="flex flex-col text-left">
              <div class="grid grid-cols-10 gap-2 items-center">
                <label class="col-span-3 text-gray-700 font-medium">
                  {{ field.label_tag }}
                </label>
                <div class="col-span-7">
                  {{ field }}
                </div>
              </div>
              <div class="grid grid-cols-10 gap-2 items-center">
                <div class="col-span-3"></div>
                <div class="!text-red-500 col-span-7 text-sm mt-1">{{ field.errors }}</div>
              </div>
            </div>
          {% endfor %}
          <button type="submit" class="w-full py-3 bg-blue-500 text-white text-lg rounded-lg hover:bg-blue-600 transition-colors cursor-pointer">
            회원가입
          </button>
        </form>
    
        <div class="mt-6 text-sm">
          이미 계정이 있으신가요?
          <a href="{% url 'users:main' %}" class="text-blue-600 hover:underline">로그인</a>
        </div>
      </div>
    </div>
    

    필드마다 Tailwind 스타일을 적용하여 폼 UI를 직관적이고 반응형으로 구성합니다.


    ⚠️ 실수 방지 체크리스트

    문제 해결 방법
    비밀번호가 그대로 저장됨 set_password() 호출 여부 확인
    회원가입은 되는데 로그인 실패 authenticate()login() 호출 여부 확인
    이미지 파일 업로드 안됨 form 태그에 enctype="multipart/form-data" 포함 여부 확인
    CSRF 에러 {% csrf_token %} 누락 여부 확인
    password2가 무시됨 clean() 메서드 구현 여부 확인

    ✅ 정리

    지금까지 사용자 정의 회원가입 폼을 직접 만들고, 이를 통해 회원가입 → 로그인까지의 전 과정을 구현했습니다. 실무에서는 이메일 인증, 비밀번호 정책 강화 등도 고려되지만, 본 강의는 그 기초 구조를 중심으로 설명하였습니다.

    • UserCreationForm을 기반으로 사용자 정의 회원가입 폼을 만들면 password1, password2 입력 및 검증이 가능해집니다.
    • Tailwind를 활용해 직관적인 입력 폼 UI를 제공할 수 있습니다.
    • save(commit=False) + set_password() 패턴은 보안상 필수입니다.
    • 회원가입 후 자동 로그인 처리까지 흐름을 마무리함으로써 실제 서비스 형태로 작동합니다.

    👉 다음 강의에서는 템플릿 상속과 재사용 구조를 설계합니다.

    TOP
    preload preload