728x90

장고에서 기본 제공하는 회원 로그인 기능과 회원가입 Form 기반 코드를 테스트하고 적어둔다.

기본 제공하는 것이라서 필요할까 싶어서 적어두지 않을까 하다가 언젠가는 필요할 수도 있을지 몰라 몇가지 기본적인 것만 적어둔다.

 

전체 소스코드 : https://github.com/jsk005/PythonDjango/tree/main/formProject

 

GitHub - jsk005/PythonDjango

Contribute to jsk005/PythonDjango development by creating an account on GitHub.

github.com

 

 

import os
from pathlib import Path
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 3rd party app
    'bootstrap4',  # add, pip install django-bootstrap4
    # local app
    'accounts.apps.AccountConfig',  # add
]
 
 
LANGUAGE_CODE = 'en-us'
 
TIME_ZONE = 'Asia/Seoul'
 
USE_I18N = True
 
USE_TZ = False
 
 
STATIC_URL = 'static/'
MEDIA_URL = 'media/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
    os.path.join(BASE_DIR, 'media'),
]
 
 
# 로그인 성공후 이동하는 URL
LOGIN_REDIRECT_URL = '/'
 

 

 

urls.py

 
# project urls.py
from django.contrib import admin
from django.urls import path
from accounts import views
from .views import homescreen_view
from django.contrib.auth import views as auth_views
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', homescreen_view, name='home'),
    path('signup/', views.register, name='signup'),
    path('login/', auth_views.LoginView.as_view(template_name='accounts/login.html'), name='login'),
    path('logout/', views.logout_view, name='logout'),
]
 

 

views.py

# project views.py
from django.shortcuts import render
 
def homescreen_view(request):
    context = {}
    return render(request, "home.html", context)
 

 

 

forms.py

회원 칼럼을 마음껏 추가하는 것은 안된다.

회원 칼럼을 원하는대로 추가하려면 Custom User Model를 사용해야 한다.

# accounts/forms.py
from django import forms
from django.contrib.auth.models import User
 
class UserForm(forms.ModelForm):
    class Meta:
        model = User
        # 장고 기본 로그인 사용으로 fields 가 제한적이다.
        # re-password 위젯을 추가해봤으나 동작하지 않더라.
        fields = ['username''email''password',]
        widgets = {
            'username': forms.TextInput(attrs={
                'class'"form-control",
                'style''max-width: 300px;',
                'placeholder''userID'
            }),
            'email': forms.EmailInput(attrs={
                'class'"form-control",
                'style''max-width: 300px;',
                'placeholder''Email'
            }),
            'password': forms.PasswordInput(attrs={
                'class'"form-control",
                'style''max-width: 300px;',
                'placeholder''비밀번호'
            }),
 
        }
        labels = {
            'username''userID',
            'email''이메일',
            'password''비밀번호',
        }
 
    # 글자수 제한
    def __init__(self*args, **kwargs):
        super(UserForm, self).__init__(*args, **kwargs)
        self.fields['username'].widget.attrs['minlength'= 6
        self.fields['username'].widget.attrs['maxlength'= 15
 

 

 

views.py

회원가입 처리 부분이다. 회원 가입 도중에 중복된 ID가 있다고 모든 입력 폼을 다시 입력해야 하는 불편함을 없애고자 jQuery Ajax 처리를 했다.

회원 가입 완료되면, return render(request, 'home.html', context) 으로 처리해도 된다.

패스워드 입력체크는 jQuery 에서 하도록 했다.

# accounts/views.py
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.views.decorators.csrf import csrf_exempt
from .forms import UserForm
 
@csrf_exempt
def register(request, *args, **kwargs):
    user = request.user
    context = {}
 
    if user.is_authenticated:
        # return HttpResponse("You are already authenticated as " + str(user.email))
        return render(request,'home.html',context)
 
    if request.POST:
        form = UserForm(request.POST)
        if form.is_valid():
            # form.save()
            account = User.objects.create_user(**form.cleaned_data)
            login(request, account)
            # return render(request, 'home.html', context)
            context['data'= '1'
            context['message'= '회원 가입 완료'
            return JsonResponse(context)
        else:
            context['data'= '0'  # 기존 가입된 회원
            context['message'= '이미 가입된 회원입니다'
            return JsonResponse(context)
    else:
        form = UserForm()
        context['form'= form
 
    return render(request, 'accounts/register.html', context)
 
 
def logout_view(request):
    logout(request)
    return redirect("home")
 

 

register.html

{% bootstrap_form form %} 과 views.py 의 register 함수의 context['form'] = form 은 굵은 색깔 부분이 같아야 한다.

비밀번호 확인은 forms.py 에서 추가가 안되어서 별도로 추가했다.

url: '{% url 'signup' %}'  과 urls.py 의 path('signup/', views.register, name='signup'), 은 굵은 색깔 부분이 같아야 한다.

jQuery ajax 는 원래 파이썬이 처리하는 기능을 가로채서 처리하므로 csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val() 와 action: 'post' 을 별도 추가해야 동작한다.

{% extends 'base.html' %}
{% load static %}
{% load bootstrap4 %}
 
{% block content %}
    <form method="POST" id="post-form">
        {% csrf_token %}
        {% bootstrap_form form %}
        <div class="form-group">
            <label for="id_repasswd">비밀번호 확인</label>
            <input type="password" name="repasswd" class="form-control" style="max-width: 300px;" required="" id="id_repasswd">
        </div>
        <button type="submit" class="btn btn-primary">가입</button>
        <a href="{% url 'home' %}">
            <button type="button" class="btn btn-warning">취소</button>
        </a>
    </form>
    <script type="text/javascript" src="{% static 'js/user/passwd_checker.js' %}"></script>
    <script>
        $(document).on('submit''#post-form'function (e) {
            e.preventDefault();
            const pwd = $("input[name=password]");
            const repwd = $("input[name=repasswd]");
            if (PasswordChk(pwd, repwd) == falsereturn false;
            $.ajax({
                type: 'POST',
                url: '{% url 'signup' %}',
                data: {
                    username: $("input[name=username]").val(),
                    email: $("input[name=email]").val(),
                    password: $("input[name=password]").val(),
                    csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
                    action: 'post'
                },
                success: function (json) {
                    if (json.data == 1) {
                        window.location.href = '/';
                        alert(json.message);
                    } else if (json.data == 0) {
                        alert(json.message);
                    }
                },
                error: function (xhr, errmsg, err) {
                    alert('에러가 발생했습니다.');
                    console.log(xhr.status + ": " + xhr.responseText);
                }
            });
        });
    </script>
{% endblock content %}
 

 

 

로그인 처리는 장고가 기본 제공하는 기능을 이용하였기 때문에 jQuery ajax 코드를 추가하면 에러가 발생한다.

jQuery ajax 처리하려면, 별도로 views.py 에서 login_view 와 같은 함수를 구현하고 login.html 에서 ajax 코드를 추가해야 한다.

 

 

 

 

블로그 이미지

Link2Me

,