티스토리 뷰

jiheestagram / urls.py

from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from django.shortcuts import redirect


class NonUserTemplateView(TemplateView):
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_anonymous:
            return reidrect('home')
        return super(NonUserTemplateView, self).dispatch(request, *args, **kwargs)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('apis/', include('apis.urls')),
    path('register/', NonUserTemplateView.as_view(template_name = 'register.html'), name = 'register'),
]

 

 

회원가입 페이지에 대한 URL 경로를 설정한다. 

NonUserTemplateView 를 사용하는 이유는 로그인과 회원가입 페이지에서 사용자의 접근을 막기위해서이다. 

이전에 사용했던 특정 클래스나 함수에서 @login_required 를 사용하는 것과 비슷한 개념이다.

이미 로그인 되어있는 사용자는 회원가입이나 로그인 페이지가 필요없다. 

로그인 되어있는 상태에서 두 페이지에 접근하면 home 을 가진 템플릿으로 이동하도록 설정한다. 

그게 아니라면 register.html 페이지로 이동한다. 

 

 

 

 

 

 

 

templates/register.html

{% extends 'base.html' %}
{% block body %}
<div class = "register">
    <div class = "container">
        <br>
        <h2 class = "text-success text-center">REGISTER</h2><br>
        <hr>
        <div class = "form-group col-md-6">
            <label for = "InputUsername" class = "text-success">Username : </label>
            <input type = "text" class = "form-control" id = "username" placeholder="Enter Usernmae">
            <small id = "emailHelp" class = "form-text text-muted">We'll never share your email with anyone else.</small>
        </div>     
        <div class = "form-group col-md-6">
            <label for = "InputEmail" class = "text-success">Email : </label>
            <input type = "email" class = "form-control" id = "email" placeholder="Enter your Email">
        </div>
        <div class = "form-group col-md-6">
            <label for = "InputPassword" class = "text-success">Password : </label>
            <input type = "password" class = "form-control" id = "password" placeholder="Enter your password">
        </div>
        <button class = "btn btn-success col-md-6" id = "register">REGISTER</button>
        <script
            src="https://code.jquery.com/jquery-3.4.1.min.js"
            integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
            crossorigin="anonymous">
        </script>
    </div>
</div>

<script>
    $(document).ready(function(){
        $('#register').click(function() {
            $.post('/apis/user/create/', 
            {'username' : $('#username').val(), 'password': $('#password').val(), 'email' : $('#email').val()},
            function() {
                alert('가입을 환영합니다!');
                window.location = {% url 'login' %};
            }).fail(function(data){
                alert(data.responseJSON.message);
            });
        });
    });
</script>

{% endblock %}

위에서 설정한 urls.py 에 의해서 register.html 으로 넘어온다.

register.html 에서는 회원가입 폼과 회원가입 버튼을 입력했을 때의 로직을 jQueyr로 정의한다.

$.post의 역할은 HTTP POST 요청 한다. { 괄호 } 안에있는 데이터들을 'apis/user/create/' 으로 전달한다.

데이터 전달에 성공하면 메세지를 띄우고 로그인 페이지로 이동한다.

데이터 전달에 실패하면 UserCreateView 에서 정의한 에러메세지를 띄운다.

 

 

 

 

 

 

 

apis/urls.py

from django.urls import path
from apis.views import UserCreateView


urlpatterns = [
    path('user/create/',UserCreateView.as_view(), name = "apis_user_create"),
]

api 호출을 위한 URL 경로이다.

위에서 호출한 'apis/user/create/' 경로는 apis.views.py 의 UserCreateView 로 이동한다.

 

 

 

 

 

 

apis/views.py

from django.core.validators import validate_email, ValidationError
from django.db import IntegrityError
from django.contrib.auth.models import User


class UserCreateView(BaseView):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(UserCreateView, self).dispatch(request, *args, **kwargs)

    def post(self, request):
        username = request.POST.gt('username', '')
        if not username:
            return self.response(message = '아이디를 입력하세요.', status = 400)
        
        password = request.POST.get('password', '')
        if not password:
            return self.response(message = '비밀번호를 입력하세요.', status = 400)

        email = request.POST.get('email', '')
        try :
            validate_email(email)
        except ValidationError:
            return self.response(message = "올바른 이메일을 입력하세요.", status = 400)

        try :
            user = User.objects.create_user(username = username, email = email, password = password)
        except IntegrityError:
            return self.response(message = "이미 존재하는 아이디입니다.", status = 400)

        return self.response({'user.id' : user.id})

register.html 에서 UserCreateView으로 post 요청하였으니 post 함수로 이동한다.

전달받은 데이터 username, password, email 각각을 검사하고 입력하지 않은 데이터가 있다면, 해당하는 에러메세지를 정의한다. 

이것도 앞서 정의한 BaseView 를 상속받았기 때문에 message, data, status 를 정의하여 JSON 형식으로 주고받을 수 있다.

모든 데이터가 제대로 입력되었다면 장고에서 제공하는 User 모듈을 사용하여 유저를 생성한다.

 

 

 

dispatch 에 대해서

http 가 어떤 방식으로 (post, get) 요청되었는지 알 수 있다.

클래스 내에서 어떤 방식으로 요청되었는지 확인하고 해당하는 요청방식 이름으로 (def post, def get) 함수를 갖는다.

함수형 뷰(Function Based View)에서는 if response.method == 'POST' : 와 같은 방식으로 해야한다. 하지만 클래스형 뷰에서는 dispatch 기능을 지원하기 때문에 편리하다.

 

 

 

 

 

실행 결과

 

댓글