본문 바로가기

인문학도 개발일지/웹프로그래밍

[수업노트] django - 회원가입, 로그인 화면 구현

 

CRUD

CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말이다. 사용자 인터페이스가 갖추어야 할 기능(정보의 참조/검색/갱신)을 가리키는 용어로서도 사용된다.

 

 

 

 

 

기본 설정

project 생성

'account' app 생성 

 

 

 

 

 

config/settings.py

# App 추가
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'account',
]



# DIRS 경로 설정
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]



# 언어코드, 시간대 설정 변경
LANGUAGE_CODE = 'ko'

TIME_ZONE = 'Asia/Seoul'


# 미디어 관련 경로 추가
MEDIA_URL = '/media/'
MEDIA_ROOT = [os.path.join(BASE_DIR, 'upload')]

 

config/urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.views.generic import TemplateView
from config import settings

urlpatterns = [
    path('', TemplateView.as_view(tempalte_name='home.html'), name='home'),
    path('admin/', admin.site.urls),
    path('account/', include('account.urls')),
    
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

 

 

account/models.py

from django.db import models

# Create your models here.
# id/pw/이름/사진

class Member(models.Model):
    email = models.EmailField(max_length=100, primary_key=True)    # 사용자가 지정한 값을 PK로
    password = models.CharField(max_length=128)
    name = models.CharField(max_length=100)
    picture = models.ImageField(upload_to='member_images')

    def __str__(self):
        return self.name

 

 

account/forms.py

from django import forms
from account.models import Member


# 회원가입 폼
class MemberJoinForm(forms.Form):
    email = forms.EmailField(
        label='이메일',
        widget=forms.EmailInput(attrs={'class':'form-control'})
    )
    password = forms.CharField(
        label='비밀번호',
        widget=forms.PasswordInput(attrs={'class':'form-control'})

    )
    re_password = forms.CharField(
        label='비밀번호 확인',
        widget=forms.PasswordInput(attrs={'class':'form-control'})
    )
    name = forms.CharField(
        label='이름',
        widget=forms.TextInput(attrs={'class':'form-control'}))
    picture = forms.ImageField(
        label='사진',
        widget=forms.FileInput(attrs={'class':'form-control'})
    )

 

 

account/views.py

from django.shortcuts import render
from django.views.generic import FormView

# 패스워드 암호화 해주는 함수.
from django.contrib.auth.hashers import make_password

from account.forms import MemberJoinForm
from account.models import Member
# Create your views here.

# 가입처리
class JoinView(FormView):
    template_name = 'account/join_form.html'
    form_class = MemberJoinForm
    success_url = '/'

 

 

 

 

 

 

account/urls.py

from django.urls import path
from account import views

app_name = 'account'

urlpatterns = [
    path('join', views.JoinView.as_view(), name='join'),
]

 

 

 

account/templates/account/join_form.html

{% extends 'base.html' %}

{% block title %}회원가입{% endblock title %}



{% block contents %}
<h2>회원가입</h2>
<!--파일업로드시-->
<form action="{% url 'account:join' %}" method="post" enctype="multipart/form-data">

    {% csrf_token %}
    {% for field in form %}
    <div class="form-group">
        <label for='{{field.id_for_label}}'>{{field.label}}</label>
        {{field}}
    </div>
    {% if field.errors %}
        <span style='color:red'>{{field.errors}}</span>
    {% endif %}
    {% endfor %}
    <input type='submit' value="가입" class='btn btn-primary'>
    <input type='reset' value="초기화" class='btn btn-primary'>

</form>


{% endblock contents %}

{% endblock contents %}

 

 

base.html 코드 수정

<li class="nav-item">
    <a class="nav-link" href="{% url 'account:join' %}">회원가입</a>
</li>   

 

 

 

 

from.py 

from django import forms
from account.models import Member


# 회원가입 폼
class MemberJoinForm(forms.Form):
    email = forms.EmailField(
        label='이메일',
        widget=forms.EmailInput(attrs={'class':'form-control'})
    )
    password = forms.CharField(
        label='비밀번호',
        widget=forms.PasswordInput(attrs={'class':'form-control'})

    )
    re_password = forms.CharField(
        label='비밀번호 확인',
        widget=forms.PasswordInput(attrs={'class':'form-control'})
    )
    name = forms.CharField(
        label='이름',
        widget=forms.TextInput(attrs={'class':'form-control'}))
    picture = forms.ImageField(
        label='사진',
        widget=forms.FileInput(attrs={'class':'form-control'})
    )


    def clean(self):
        # 요청파라미터 값들 조회
        cleaned_data = super().clean()    # dictionary 반환.
        email = cleaned_data.get('email')
        password = cleaned_data.get('password')
        re_password = cleaned_data.get('re_password')
        #password와 re_password가 같은지 체크
        if password != re_password:
            self.add_error('password', '비밀번호가 다릅니다.')
            self.add_error('re_password', '비밀번호가 다릅니다')

        # 이메일(아이디) 중복 체크
        try:
            Member.objects.get(pk=email)
            self.add_error('email', '이미 가입된 이메일입니다.')
        except:
        #     # 조회 결과가 없다. 등록되지 않은 email
            pass    

 

 

views.py

from django.shortcuts import render
from django.views.generic import FormView

# 패스워드 암호화 해주는 함수.
from django.contrib.auth.hashers import make_password

from account.forms import MemberJoinForm
from account.models import Member
# Create your views here.

# 가입처리
class JoinView(FormView):
    template_name = 'account/join_form.html'
    form_class = MemberJoinForm
    success_url = '/'

    # 검증이 끝난 Form을 받아서 비즈니스 로직(가입처리) 처리하는 함수.
    def form_valid(self, form):
        cleaned_data = form.cleaned_data    # dictionary
        email = cleaned_data.get('email')
        password = make_password(cleaned_data.get('password'))   # 암호화 처리
        name = cleaned_data.get('name')
        picture = cleaned_data.get('picture')
        member = Member(email=email, password=password, name=name, picture=picture)
        member.save()

        return super().form_valid(form)
    

 

 

forms.py

# 로그인 폼
class LoginForm(forms.Form):
    email = forms.EmailField(
        label='이메일',
        widget=forms.EmailInput(attrs={'class':'form-control'})
    )
    password = forms.CharField(
        label='비밀번호',
        widget=forms.PasswordInput(attrs={'class':'form-control'})

 

views.py

from account.forms import MemberJoinForm, LoginForm

# 로그인 처리 View
class LoginView(FormView):
    template_name = 'account/login_form.html'
    form_class = LoginForm
    success_url = '/'    # 메인으로

 

 

 

urls.py 추가

from django.urls import path
from account import views

app_name = 'account'

urlpatterns = [
    path('join', views.JoinView.as_view(), name='join'),
    path('login', views.LoginView.as_view(), name='login'),
]

 

 

login_form.html

{% extends 'base.html' %}

{% block title %}
{% endblock title %}

{% block contents %}
<form action = '{% url "account:login" %}' method="post">
    {% csrf_token %}
    {% for field in form %}
    <div class="form-group">
        <label for="{{field.id_for_label}}">{{field.label}}</label>
        {{field}}
    </div>
    <span style="color:red">{{field.errors}}</span>
    {% endfor %}
    <input type = 'submit' value="로그인" class="btn btn-primary">
    <a href='{% url "account:join" %}' class='btn btn-primary'>회원가입</a>

</form>
{% endblock contents %}

 

 

base.html 코드 추가

<li class="nav-item">
     <a class="nav-link" href="{% url 'account:login' %}">로그인</a>
</li>