2020-03-26

Django 07. 회원가입 구현

Django에서 제공하는 내장 Form을 사용하여 회원가입과 Validation을 구현합니다.


1. forms.py 추가

Django는 form을 통해 커스텀되고 생성된 필드를 templates과 연결하여 사용할 수 있습니다. form에서 지정된 필드에 따라 validation 처리를 해주며, form으로 넘긴 입력 필드를 as_p() 등과 같은 기능을 사용함으로써 간결한 html 작성이 가능하다는 장점이 있습니다.

이 프로젝트는 기본적으로 회원가입이 컴퓨터공학부 전용, 일반인 전용 두가지로 나누어져 있습니다. 입력필드는 대부분 같고 필수, 선택사항 필드만 다르기에 일반인 회원가입은 포스팅에서 생략하도록 하겠습니다.

users app 내에 forms.py 파일을 생성한 후 django의 내장 form인 UserCreationForm을 상속받는 CsRegisterForm 클래스를 생성하고 아래와 같이 코드를 입력합니다. 우선 아이디와 비밀번호 필드만 추가하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# users/forms.py

from django import forms
from .models import User
from django.contrib.auth.forms import UserCreationForm

def hp_validator(value):
if len(str(value)) != 10:
raise forms.ValidationError('정확한 핸드폰 번호를 입력해주세요.')

def student_id_validator(value):
if len(str(value)) != 8:
raise forms.ValidationError('본인의 학번 8자리를 입력해주세요.')

class CsRegisterForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(CsRegisterForm, self).__init__(*args, **kwargs)

self.fields['user_id'].label = '아이디'
self.fields['user_id'].widget.attrs.update({
'class': 'form-control',
'autofocus': False
})
self.fields['password1'].label = '비밀번호'
self.fields['password1'].widget.attrs.update({
'class': 'form-control',
})

class Meta:
model = User
fields = ['user_id', 'password1', 'password2', 'email', 'name', 'hp', 'grade', 'student_id', 'circles']

def save(self, commit=True):
user = super(CsRegisterForm, self).save(commit=False)
user.level = '2'
user.department = '컴퓨터공학부'
user.save()

return user

widget 커스텀, validations을 수정이 가능하도록 init 메소드로 초기화 후 form을 작성합니다.

save 함수를 보시면 컴퓨터공학부 회원가입을 통해 생성된 사용자는 level 2의 권한을 가지며, department 필드가 컴퓨터공학부로 저장됩니다.

Django 내장폼 공식문서

2. views.py 작성

django의 generic view인 CreateView를 import하여 회원가입 CBV를 구현하겠습니다. 아래의 소스를 기존의 views.py에 추가해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# users/views.py

from django.core.exceptions import PermissionDenied
from .forms import CsRegisterForm
from django.views.generic import CreateView

class CsRegisterView(CreateView):
model = User
template_name = 'users/register_cs.html'
form_class = CsRegisterForm

def get(self, request, *args, **kwargs):
if not request.session.get('agreement', False):
raise PermissionDenied
request.session['agreement'] = False
return super().get(request, *args, **kwargs)

def get_success_url(self):
messages.success(self.request, "회원가입 성공.")
return redirect('users:login')

def form_valid(self, form):
self.object = form.save()
return redirect(self.get_success_url())

회원가입 창으로 redirect시 get함수를 통해 이전 포스팅에서 구현한 agreement 세션값을 검사하게 됩니다. 만약 사용자가 약관에 동의를 안했을시 403 에러가 발생하도록 PermissionDenied처리를 해줍니다.

POST시 form에서 validations 검증이 성공했다면 get_success_url()로 넘어가 Success 메세지와 함께 login 경로로 redirect 되도록 구현합니다.

Django 내장 CBV API 공식문서

3. urls.py 작성

기존 urls.pyurlpatterns에 회원가입 url을 추가해줍니다.

1
2
3
4
5
6
# users/urls.py

urlpatterns = [
path('agreement/', views.AgreementView.as_view(), name='agreement'),
path('csregister/', views.CsRegisterView.as_view(), name='csregister'), # 추가
]

4. templates 작성

templatesusers 내에 register_cs.html을 생성하고 아래의 소스를 입력합니다. (전체 코드는 생략하고 form 태그의 아이디 입력필드만 포스팅하겠습니다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!-- templates/users/register_cs.html -->

<form action="" id="signup" method="POST" novalidate>
{% csrf_token %}
<div>
<label name="label_user_id" for="{{ form.user_id.id_for_label }}">
{{ form.user_id.label }}
</label>
{{ form.user_id }}
<script type="text/javascript">
if (document.getElementsByName('user_id')[0].value != '') {
document.getElementsByName('label_user_id')[0].setAttribute('class','active');
}
</script>

{% if form.user_id.errors %}
<script type="text/javascript">
document.getElementsByName('user_id')[0].setAttribute('class', 'form-control is-invalid')
</script>
{% for error in form.user_id.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% endif %}

<small>
로그인 시 사용할 아이디를 입력해주세요.
</small>
</div>
//
</form>

form의 입력필드는 html에서 { { form.user_id } } 같은 형식으로 사용될 수 있습니다.

중간 중간 삽입되어 있는 script는 회원가입 에러 처리를 위한 script로 부트스트랩 플러그인 유료버전에 제공되어 있는 기능을 보고 javascript로 구현한 것입니다.

5. 결과

django-project-07

django-project-07

*전체 html, css 등은 자세하게 포스팅하지 않습니다. 제 Github에서 소스를 확인하실 수 있습니다.