Post

Django: 모델(Model)과 ORM 및 폼(Form) 처리, 사용자 인증(Authentication)

Django의 모델(Model)과 ORM(Object Relational Mapping), 폼(Form) 처리, 사용자 인증(Authentication)

Django: 모델(Model)과 ORM 및 폼(Form) 처리, 사용자 인증(Authentication)

7. 모델(Model)과 ORM

Django의 모델(Model)은 데이터베이스 구조를 정의하며, Django ORM(Object Relational Mapping)을 통해 데이터베이스와 상호작용합니다. 이 섹션에서는 모델 생성, 관계 정의, 데이터베이스 작업을 다룹니다.

7.1 Django 모델의 역할

  • 데이터베이스 테이블과 매핑됩니다.
  • 데이터를 추가, 수정, 삭제, 조회할 수 있는 인터페이스를 제공합니다.
  • Django의 ORM을 통해 SQL을 직접 작성하지 않아도 데이터베이스 작업을 수행할 수 있습니다.

7.2 모델 생성

1. 모델 정의

  • models.py 파일에 클래스를 정의합니다:

    1
    2
    3
    4
    5
    6
    7
    8
    
      from django.db import models
        
      class Post(models.Model):
          title = models.CharField(max_length=100)  # 짧은 문자열
          content = models.TextField()             # 긴 텍스트
          created_at = models.DateTimeField(auto_now_add=True)  # 생성 날짜
          updated_at = models.DateTimeField(auto_now=True)      # 수정 날짜
        
    

2. 모델 등록

  • 앱의 admin.py 파일에 모델을 등록하여 Django Admin에서 관리 가능:

    1
    2
    3
    4
    5
    
      from django.contrib import admin
      from .models import Post
        
      admin.site.register(Post)
        
    

7.3 데이터베이스 설정 및 마이그레이션

1. 데이터베이스 설정

  • 기본 데이터베이스는 SQLite이며, settings.py에서 설정을 확인할 수 있습니다:

    1
    2
    3
    4
    5
    6
    7
    
      DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.sqlite3',
              'NAME': BASE_DIR / 'db.sqlite3',
          }
      }
        
    

2. 마이그레이션 파일 생성

  • 모델을 데이터베이스에 반영하려면 마이그레이션 파일을 생성:

    1
    2
    
      python manage.py makemigrations
        
    

3. 마이그레이션 실행

  • 마이그레이션을 적용하여 데이터베이스에 테이블 생성:

    1
    2
    
      python manage.py migrate
        
    

7.4 모델 필드와 속성

Django에서 제공하는 주요 모델 필드:

필드 타입설명
CharField짧은 문자열 (길이 제한 필수)
TextField긴 텍스트
IntegerField정수
FloatField실수
BooleanField불리언
DateTimeField날짜와 시간
ForeignKey다른 모델과의 1:N 관계
ManyToManyField다른 모델과의 N:M 관계

7.5 모델 간 관계 정의

1. 1:N 관계

  • ForeignKey를 사용:

    1
    2
    3
    4
    
      class Comment(models.Model):
          post = models.ForeignKey(Post, on_delete=models.CASCADE)  # 연결된 게시글 삭제 시 함께 삭제
          content = models.TextField()
        
    

2. N:M 관계

  • ManyToManyField를 사용:

    1
    2
    3
    4
    5
    6
    7
    
      class Tag(models.Model):
          name = models.CharField(max_length=30)
        
      class Post(models.Model):
          title = models.CharField(max_length=100)
          tags = models.ManyToManyField(Tag)
        
    

7.6 ORM의 기본 쿼리셋 활용

1. 데이터 추가

  • 새로운 데이터를 추가:

    1
    2
    
      post = Post.objects.create(title="First Post", content="This is my first post!")
        
    

2. 데이터 조회

  • 모든 데이터 조회:

    1
    2
    
      posts = Post.objects.all()
        
    
  • 조건부 조회:

    1
    2
    3
    
      post = Post.objects.get(id=1)  # 단일 객체 조회
      filtered_posts = Post.objects.filter(title__contains="First")  # 조건부 조회
        
    

3. 데이터 수정

  • 객체를 수정하고 저장:

    1
    2
    3
    4
    
      post = Post.objects.get(id=1)
      post.title = "Updated Title"
      post.save()
        
    

4. 데이터 삭제

  • 객체 삭제:

    1
    2
    3
    
      post = Post.objects.get(id=1)
      post.delete()
        
    

7.7 관리자 페이지(Custom Admin)

1. 관리자 페이지 설정

  • admin.py에서 모델을 커스터마이징:

    1
    2
    3
    4
    5
    6
    
      class PostAdmin(admin.ModelAdmin):
          list_display = ('title', 'created_at', 'updated_at')
          search_fields = ('title',)
        
      admin.site.register(Post, PostAdmin)
        
    

2. 관리자 페이지 접근

  • 서버 실행 후 /admin/ 경로에서 관리자 페이지에 로그인.

8. 폼(Form) 처리

Django의 폼(Form) 시스템은 HTML 폼을 생성하고 데이터를 검증하는 강력한 도구를 제공합니다. 사용자 입력 데이터를 처리하는 데 사용되며, 기본 폼 클래스와 모델 폼을 통해 구현할 수 있습니다.

8.1 Django 폼 개념

  • 폼 클래스: HTML 폼을 생성하고 유효성을 검사하며 데이터를 처리.
  • ModelForm: 모델 기반의 폼으로, 데이터베이스 모델과 연결.

8.2 폼 클래스 정의 및 사용

1. 폼 클래스 정의

  • 앱의 forms.py 파일에 폼 클래스를 작성:

    1
    2
    3
    4
    5
    6
    
      from django import forms
        
      class PostForm(forms.Form):
          title = forms.CharField(max_length=100, label='제목')
          content = forms.CharField(widget=forms.Textarea, label='내용')
        
    

2. 폼 사용하기

  1. 뷰에서 폼 렌더링
    • views.py에서 폼을 생성하고 템플릿으로 전달:

      1
      2
      3
      4
      5
      6
      7
      
        from django.shortcuts import render
        from .forms import PostForm
              
        def create_post(request):
            form = PostForm()
            return render(request, 'create_post.html', {'form': form})
              
      
  2. 템플릿에서 폼 출력
    • create_post.html 파일:

      1
      2
      3
      4
      5
      6
      7
      
              
        <form method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit">Submit</button>
        </form>
              
      

8.3 유효성 검사와 에러 처리

유효성 검사

  • 폼에서 데이터가 유효한지 확인:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      def create_post(request):
          if request.method == 'POST':
              form = PostForm(request.POST)
              if form.is_valid():
                  title = form.cleaned_data['title']
                  content = form.cleaned_data['content']
                  # 데이터를 처리 (예: 데이터베이스에 저장)
          else:
              form = PostForm()
          return render(request, 'create_post.html', {'form': form})
        
    

에러 처리

  • 유효성 검사를 통과하지 못한 경우 에러 메시지가 표시됩니다.
  • 템플릿에서 에러 메시지 출력:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
        
      {% for field in form %}
          <p>{{ field.label }}: {{ field }}
          {% for error in field.errors %}
              <span style="color: red;">{{ error }}</span>
          {% endfor %}
          </p>
      {% endfor %}
        
    

8.4 ModelForm 활용

1. ModelForm 정의

  • forms.ModelForm을 상속받아 모델 기반 폼 생성:

    1
    2
    3
    4
    5
    6
    7
    8
    
      from django import forms
      from .models import Post
        
      class PostModelForm(forms.ModelForm):
          class Meta:
              model = Post
              fields = ['title', 'content']
        
    

2. ModelForm 사용

  • views.py에서 ModelForm 처리:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      from .forms import PostModelForm
        
      def create_post(request):
          if request.method == 'POST':
              form = PostModelForm(request.POST)
              if form.is_valid():
                  form.save()  # 모델 인스턴스를 자동 저장
          else:
              form = PostModelForm()
          return render(request, 'create_post.html', {'form': form})
        
    

8.5 파일 업로드 처리

1. 파일 필드 추가

  • 모델에 파일 필드 추가:

    1
    2
    3
    4
    5
    
      class Post(models.Model):
          title = models.CharField(max_length=100)
          content = models.TextField()
          file = models.FileField(upload_to='uploads/', blank=True, null=True)
        
    

2. 파일 업로드 폼

  • 파일 업로드를 처리하려면 enctype="multipart/form-data"를 설정:

    1
    2
    3
    4
    5
    6
    7
    
        
      <form method="post" enctype="multipart/form-data">
          {% csrf_token %}
          {{ form.as_p }}
          <button type="submit">Submit</button>
      </form>
        
    

3. 파일 저장 처리

  • 뷰에서 파일 데이터 처리:

    1
    2
    3
    
      if form.is_valid():
          form.save()
        
    

9. 사용자 인증(Authentication)

Django는 강력하고 유연한 인증 시스템을 제공합니다. 이 시스템은 사용자 관리, 로그인/로그아웃, 회원가입, 비밀번호 관리 등의 기능을 포함합니다.

9.1 Django 기본 인증 시스템

1. Django의 기본 User 모델

  • Django는 기본적으로 User 모델을 제공하며, 인증 및 권한 관리를 지원합니다.
  • 기본 User 모델 필드:
    • username, password, email, first_name, last_name

2. Django의 인증 관련 앱

  • 기본적으로 설치된 앱:
    • django.contrib.auth: 인증 및 권한 관리
    • django.contrib.sessions: 세션 관리

3. 관리자 페이지에서 User 관리

  • 관리자 페이지에서 기본 User 모델 관리:
    • /admin/에서 사용자 추가, 편집 가능.

9.2 로그인/로그아웃 구현

1. 로그인

  • Django의 기본 로그인 뷰를 사용:

    1
    2
    3
    4
    5
    
      from django.contrib.auth.views import LoginView
        
      class CustomLoginView(LoginView):
          template_name = 'login.html'
        
    
  • URL 설정:

    1
    2
    3
    4
    5
    6
    7
    
      from django.urls import path
      from .views import CustomLoginView
        
      urlpatterns = [
          path('login/', CustomLoginView.as_view(), name='login'),
      ]
        
    
  • 템플릿(login.html):

    1
    2
    3
    4
    5
    6
    7
    
        
      <form method="post">
          {% csrf_token %}
          {{ form.as_p }}
          <button type="submit">Login</button>
      </form>
        
    

2. 로그아웃

  • Django의 기본 로그아웃 뷰를 사용:

    1
    2
    3
    4
    5
    
      from django.contrib.auth.views import LogoutView
        
      class CustomLogoutView(LogoutView):
          template_name = 'logged_out.html'
        
    
  • URL 설정:

    1
    2
    3
    4
    
      urlpatterns += [
          path('logout/', CustomLogoutView.as_view(), name='logout'),
      ]
        
    
  • 로그아웃 템플릿(logged_out.html):

    1
    2
    3
    
        
      <p>You have been logged out. <a href="{% url 'login' %}">Login again</a></p>
        
    

9.3 회원가입 구현

1. 회원가입 뷰

  • forms.py에 회원가입 폼 작성:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      from django import forms
      from django.contrib.auth.models import User
      from django.contrib.auth.forms import UserCreationForm
        
      class RegisterForm(UserCreationForm):
          email = forms.EmailField()
        
          class Meta:
              model = User
              fields = ['username', 'email', 'password1', 'password2']
        
    
  • views.py에 회원가입 뷰 작성:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
      from django.shortcuts import render, redirect
      from .forms import RegisterForm
        
      def register(request):
          if request.method == 'POST':
              form = RegisterForm(request.POST)
              if form.is_valid():
                  form.save()
                  return redirect('login')
          else:
              form = RegisterForm()
          return render(request, 'register.html', {'form': form})
        
    
  • URL 설정:

    1
    2
    3
    4
    
      urlpatterns += [
          path('register/', register, name='register'),
      ]
        
    
  • 회원가입 템플릿(register.html):

    1
    2
    3
    4
    5
    6
    7
    
        
      <form method="post">
          {% csrf_token %}
          {{ form.as_p }}
          <button type="submit">Register</button>
      </form>
        
    

9.4 사용자 프로필 관리

사용자 모델 확장

  • 기본 User 모델을 확장하기 위해 OneToOne 관계로 연결:

    1
    2
    3
    4
    5
    6
    7
    8
    
      from django.db import models
      from django.contrib.auth.models import User
        
      class Profile(models.Model):
          user = models.OneToOneField(User, on_delete=models.CASCADE)
          bio = models.TextField(blank=True)
          profile_image = models.ImageField(upload_to='profile_images/', blank=True)
        
    

신호(Signal)로 프로필 생성

  • 새로운 사용자가 생성되면 자동으로 프로필 생성:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      from django.db.models.signals import post_save
      from django.dispatch import receiver
      from .models import Profile
        
      @receiver(post_save, sender=User)
      def create_profile(sender, instance, created, **kwargs):
          if created:
              Profile.objects.create(user=instance)
        
    

9.5 비밀번호 관리

1. 비밀번호 변경

  • 기본 제공 뷰를 사용:

    1
    2
    3
    4
    5
    
      from django.contrib.auth.views import PasswordChangeView
        
      class CustomPasswordChangeView(PasswordChangeView):
          template_name = 'password_change.html'
        
    
  • URL 설정:

    1
    2
    3
    4
    
      urlpatterns += [
          path('password_change/', CustomPasswordChangeView.as_view(), name='password_change'),
      ]
        
    
  • 템플릿(password_change.html):

    1
    2
    3
    4
    5
    6
    7
    
        
      <form method="post">
          {% csrf_token %}
          {{ form.as_p }}
          <button type="submit">Change Password</button>
      </form>
        
    

2. 비밀번호 초기화

  • Django에서 제공하는 비밀번호 초기화 뷰:

    1
    2
    3
    4
    5
    
      from django.contrib.auth.views import PasswordResetView
        
      class CustomPasswordResetView(PasswordResetView):
          template_name = 'password_reset.html'
        
    
  • URL 설정:

    1
    2
    3
    4
    
      urlpatterns += [
          path('password_reset/', CustomPasswordResetView.as_view(), name='password_reset'),
      ]
        
    
This post is licensed under CC BY 4.0 by the author.