참고문서


회원가입을 위한 form, view, template, url구현

member/forms.py

from django import forms
from django.contrib.auth import get_user_model

User = get_user_model()


class LoginForm(forms.Form):
    ...


class SignupForm(forms.Form):
    username = forms.CharField(
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
            }
        )
    )
    password1 = forms.CharField(
        widget=forms.PasswordInput(
            attrs={
                'class': 'form-control',
            }
        )
    )
    # 비밀번호 확인을 위한 필드
    password2 = forms.CharField(
        widget=forms.PasswordInput(
            attrs={
                'class': 'form-control',
            }
        )
    )

    # username필드의 검증에 username이 이미 사용중인지 여부 검사
    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError('아이디가 이미 사용중입니다')
        return username

    # password1와 password2의 값이 일치하는지 유효성 검사
    def clean_password2(self):
        password1 = self.cleaned_data['password1']
        password2 = self.cleaned_data['password2']
        if password1 != password2:
            raise forms.ValidationError('비밀번호와 비밀번호 확인란의 값이 일치하지 않습니다')
        return password2

    # 자신이 가진 username과 password를 사용해서 유저 생성 후 반환하는 메서드
    def signup(self):
        if self.is_valid():
            return User.objects.create_user(
                username=self.cleaned_data['username'],
                password=self.cleaned_data['password2']
            )

member/views.py

from .forms import LoginForm, SignupForm
...
...

def signup(request):
    if request.method == 'POST':
        signup_form = SignupForm(request.POST)
        # 유효성 검증에 통과한 경우 (username의 중복과 password1, 2의 일치 여부)
        if signup_form.is_valid():
            # SignupForm의 인스턴스 메서드인 signup() 실행, 유저 생성
            signup_form.signup()
            return redirect('post:post_list')
    else:
        signup_form = SignupForm()

    context = {
        'signup_form': signup_form,
    }
    return render(request, 'member/signup.html', context)

templates/member/signup.html

{% extends 'base.html' %}

{% block title %}Signup{% endblock %}
{% block content %}
<div class="signup">
	<form action="" method="post">
		{% csrf_token %}
		{% for field in signup_form %}
			<div class="form-group{% if field.errors %} has-error{% endif %}">
				{{ field.label_tag }}
				{{ field }}
				{% if field.errors %}
					{% for error in field.errors %}
					<span class="help-block">{{ error }}</span>
					{% endfor %}
				{% endif %}
			</div>
		{% endfor %}

		{% if signup_form.non_field_errors %}
			{% for error in login_form.non_field_errors %}
			<p class="text-danger"><b>{{ error }}</b></p>
			{% endfor %}
		{% endif %}
		<button class="btn btn-primary btn-block">회원가입</button>
	</form>
</div>
{% endblock %}

member/urls.py

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^login/$', views.login, name='login'),
    url(r'^logout/$', views.logout, name='logout'),
    url(r'^signup/$', views.signup, name='signup'),
]

비슷한 코드를 공유하는 form부분을 include처리

templates/include/form.html

<form action="" method="post">
	{% csrf_token %}
	{% for field in form %}
		<div class="form-group{% if field.errors %} has-error{% endif %}">
			{{ field.label_tag }}
			{{ field }}
			{% if field.errors %}
				{% for error in field.errors %}
				<span class="help-block">{{ error }}</span>
				{% endfor %}
			{% endif %}
		</div>
	{% endfor %}

	{% if form.non_field_errors %}
		{% for error in login_form.non_field_errors %}
		<p class="text-danger"><b>{{ error }}</b></p>
		{% endfor %}
	{% endif %}
	<button class="btn btn-primary btn-block">{{ submit_title }}</button>
</form>

templates/member/login.html

{% extends 'base.html' %}

{% block title %}Login{% endblock %}
{% block content %}
<div class="login">
	{% include 'include/form.html' with form=login_form submit_title='로그인' %}
</div>
{% endblock %}

templates/member/signup.html

{% extends 'base.html' %}

{% block title %}Signup{% endblock %}
{% block content %}
<div class="signup">
	{% include 'include/form.html' with form=signup_form submit_title='회원가입' %}
</div>
{% endblock %}