본문 바로가기
Web Backend/Django

[Django] Django 학습 정리 - Django Auth

by 요호유후 2025. 3. 30.
반응형

지금까지 Django 학습한 내용을 바탕으로 정리를 해보려 한다.

 

목차
1. Django User 모델
  1-1. 기본 User 모델
  1-2. 커스텀 User 모델
2. 인증 관련 함수
[작업 환경]
MacOS, PyCharm
pyenv, poetry
Python, Django

 

 

1. Django User 모델

1. 기본 User 모델

Django는 기본적으로 username, password, email, first_name, last_name 등의 필드를 가진 기본 User 모델을 제공
따라서, 별도의 코드 작성 없이(model, form, setting) 사용할 수 있다.

[코드 작성 필요]
- views.py : 회원가입, 로그인, 로그아웃 기능 구현
- config/urls.py : 기본 auth URL include 가능

[코드 작성 불필요]
- models.py (db) : 코드작성 불필요, 기본 User 모델이 적용됨 (관계 및 Manager 정의 시 작성)
- forms.py (입력 UI) : 코드작성 불필요, 기본 제공 Form 사용 가능 (입력 UI 커스텀 필요 시 작성)
- config/settings.py : AUTH_USER_MODEL 설정 불필요

    ⭐️ 주의사항

Django 기본 유저 모델은 이미 마이그레이션 상태로 제공되기 때문에
필드 수정, 삭제, 추가 등 직접적인 커스터마이징은 어렵고 위험하다.

    📌 사용예시)

# model.py, forms.py 코드 작성 필요 없이 기본 제공

# /views.py
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.shortcuts import render, redirect
from django.conf import settings
from django.contrib.auth import login as django_login
from django.contrib.auth import logout as django_logout
from django.urls import reverse

def sign_up(request):	# 회원가입
    form = UserCreationForm(request.POST or None) # POST 이거나 get(아무것도 안 넣어줘도 되는 것)
   
    if form.is_valid():
        form.save()
        return redirect(settings.LOGIN_URL)
       
    context = {
        'form': form
    }

    return render(request, 'registration/signup.html', context)

def login(request):	# 로그인
    form = AuthenticationForm(request, request.POST or None)

    if form.is_valid():
        django_login(request, form.get_user()) 
        
        next = request.GET.get('next')
        if next:
            return redirect(next)

        return redirect(reverse('blog:list')) # name을 입력해서 url을 반환 해줌

    context = {'form': form}

    return render(request, 'registration/login.html', context)

def logout(request):	# 로그아웃
    django_logout(request) # 사용자 세션 삭제 및 로그아웃 처리

    return redirect(settings.LOGOUT_REDIRECT_URL)

 

# config/urls.py

urlpatterns = [
	path('accounts/', include("django.contrib.auth.urls")),
]

 

2. 커스텀 User 모델

기본 User 모델 외에 필드를 추가하고 싶을 때 사용하는 모델
커스텀 User 모델은 2개의 베이스 클래스로 구분된다.

[코드 작성]
- views.py : 회원가입, 로그인, 로그아웃 기능 구현
- config/urls.py : URL 매핑
-  models.py (db) : 커스텀 User 모델 작성
- forms.py (입력 UI) : 코드작성 필수는 아님, 기본 제공 Form 사용 가능 (입력 UI 커스텀 필요 시 작성)
- config/settings.py : AUTH_USER_MODEL 작성 필요

       ⭐️ 주요설정

커스텀 User 모델을 사용할 경우 Django에 알려 줘야 한다!

1. 유저모델 설정
    config/setting.py에 AUTH_USER_MODEL = '<앱이름>/<커스텀유저모델이름>'
   예) AUTH_USER_MODEL = 'accounts/CustomUser'
2. 유저모델 호출
    get_user_model() 함수로 호출 한다.

 

    1️⃣ AbstractUser 클래스

기본 Django 유저 모델을 그대로 상속 받아서 필요한 필드만 커스터마이징할 때 사용한다.
username, email, password, first_name, last_name 등의 기본 필드가 포함되어 있다.

        ⭐️ 주의사항

기본 필드를 상속 받기 때문에, 필드 수정이 일부 제한적이고 삭제는 어렵고 비효율적이다.

        📌 사용예시)

# member/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

# 기본필드(username, email, first_name 등) + nickname, profile_image 필드 추가
class User(AbstractUser):
    nickname = models.CharField(max_length=30, unique=True)
    profile_image = models.ImageField(upload_to='profile/', blank=True)

    def __str__(self):
        return self.nickname
        
        
# config/settings.py
AUTH_USER_MODEL = 'member.User'


# member/forms.py
from django.contrib.auth.forms import UserCreationForm
from .models import User

class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'nickname', 'password1', 'password2']
        
        
# member/urls.py
from django.urls import path
from .views import signup

app_name = 'member'

urlpatterns = [
    path('signup/', signup, name='signup'),
]


# config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('member/', include('member.urls')),  # <-- 이 부분
]

         ⭐️ 위 예시 기준 migrations 정보

fields=[
	# 기본 유저 모델 필드
    ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    ('password', models.CharField(max_length=128, verbose_name='password')),
    ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
    ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
    ('username', models.CharField(max_length=150, unique=True, verbose_name='username')),
    ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
    ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
    ('email', models.EmailField(blank=True, max_length=254, verbose_name='email')),
    ('is_staff', models.BooleanField(default=False, verbose_name='staff status')),
    ('is_active', models.BooleanField(default=True, verbose_name='active')),
    ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
    
    # 커스텀 필드
    ('nickname', models.CharField(max_length=30, unique=True)),
    ('profile_image', models.ImageField(upload_to='profile/', blank=True)),
    ],

 

    2️⃣ AbstractBaseUser 클래스

User 모델을 완전 새롭게 정의할 때 사용한다.
password, last_login만 제공되고 나머지 필드는 전부 직접 정의해야 한다.

        📌 사용예시)

class User(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email',
        unique=True
    )
    is_active = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    nickname = models.CharField('nickname', max_length=20, unique=True)

    following = models.ManyToManyField(
        'self', symmetrical=False, related_name='followers',
        through='UserFollowing', through_fields=('from_user', 'to_user')
    )

    objects = UserManager()
    USERNAME_FIELD = 'email' # 원래 기본은 user, 대신 email로 사용하기 위해 선언
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = []

         ⭐️ 위 예시 기준 migrations 정보

fields=[
	# 기본 제공 필드
    ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
    ('password', models.CharField(max_length=128, verbose_name='password')),
    ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
    
    # 커스텀 필드
    ('email', models.EmailField(max_length=254, unique=True, verbose_name='email')),
    ('is_active', models.BooleanField(default=False)),
    ('is_admin', models.BooleanField(default=False)),
    ('nickname', models.CharField(max_length=20, unique=True, verbose_name='nickname')),
],

 

3. Django User 모델 정리

Django에서 기본적으로 제공하는 필드만 사용할 예정이다. → 기본 User 모델
Django에서 기본 제공하는 필드 외 추가로 닉네임, 연락처 필드를 사용할 예정이다. → 커스텀 User 모델(AbstractUser)
필드로 email, 연락처, 비밀번호만 있으면 된다. → 커스텀 User 모델(AbstractBaseUser)

 

 

2. 인증 관련 함수

1. authenticate()

사용자 인증 처리 함수로, 아이디/비밀번호가 올바른지 확인해준다.

    📌 사용예시)

from django.contrib.auth import authenticate

def clean(self):
    cleaned_data = super().clean()
    email = cleaned_data.get('email')
    password = cleaned_data.get('password')

    self.user = authenticate(email=email, password=password) # 인증 성공 시 User 객체 반환, 실패 시 None 반환

    if not self.user:
        raise forms.ValidationError('이메일 또는 패스워드가 올바르지 않습니다.')

    if not self.user.is_active:
        raise forms.ValidationError('유저가 인증되지 않았습니다.')
    return cleaned_data

 

2. login()

인증된 사용자 객체를 로그인 처리해서 세션에 등록한다.

    📌 사용예시)

from django.contrib.auth import authenticate, login

def login_view(request):
    user = authenticate(request, username='testuser', password='password123')
    if user is not None:
        login(request, user)
        return redirect('home')

 

3. logout()

현재 로그인된 사용자의 세션을 종료한다. (로그아웃 처리)

    📌 사용예시)

from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    return redirect('home')

 

4. @login_required (LoginRequiredMixin)

로그인이 안 된 사용자는 특정 뷰에 접근하지 못하도록 한다. (자동 리다이렉트 됨)
FBV에서는 @login_required를 사용하고 CBV에서는 LoginRequriedMixin을 상속 받는다.

    📌 사용예시)

# FBV
@login_required()
def blog_create(request):
	pass

# CBV
class BlogCreateView(LoginRequiredMixin, CreateView):
	pass

 

 

 

반응형

댓글