본문 바로가기

Backup/Django

[Django #6] User Registration

이번장에서는 user account에 대한 부분을 작업해볼것이다.


login, logout, register, 또 우리가 로그인 하였다면 로그인된 상태도 페이지에 반영하게 할것이다.

일단 Django에서 제공해주는 User model을 쓸건데 여기에서 제공되는 기능들이 무엇인지 한번 살펴보자

$ python3 manage.py shell Python 3.7.2 (v3.7.2:9a3ffc0492, Dec 24 2018, 02:44:43) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django.contrib.auth.models import User >>> dir(User) ['DoesNotExist', 'EMAIL_FIELD', 'Meta', 'MultipleObjectsReturned', 'REQUIRED_FIELDS', 'USERNAME_FIELD', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_column_name_clashes', '_check_field_name_clashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_check_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_managers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_property_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable', '_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_password', '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_val', 'check', 'check_password', 'clean', 'clean_fields', 'date_error_message', 'date_joined', 'delete', 'email', 'email_user', 'first_name', 'from_db', 'full_clean', 'get_all_permissions', 'get_deferred_fields', 'get_email_field_name', 'get_full_name', 'get_group_permissions', 'get_next_by_date_joined', 'get_previous_by_date_joined', 'get_session_auth_hash', 'get_short_name', 'get_username', 'groups', 'has_module_perms', 'has_perm', 'has_perms', 'has_usable_password', 'id', 'is_active', 'is_anonymous', 'is_authenticated', 'is_staff', 'is_superuser', 'last_login', 'last_name', 'logentry_set', 'natural_key', 'normalize_username', 'objects', 'password', 'pk', 'prepare_database_save', 'refresh_from_db', 'save', 'save_base', 'serializable_value', 'set_password', 'set_unusable_password', 'unique_error_message', 'user_permissions', 'username', 'username_validator', 'validate_unique'] >>>


우선 registration page를 만들어보기 전에 M, V, and C (model, view, and controller)를 고려해야 함을 명심해자.


그럼 우선적으로 main templates에서 home html를 복사해서 register.html를 만들고 아래와 같이 고쳐보자

{% extends 'main/header.html' %} {% block content %} <form method="POST"> {% csrf_token %} {{form}} </form> If you already have an account <a href="/login" target="blank"><strong>login</strong></a> instead. {% endblock %}


우선 form tag란 여기에 form형식이 들어올거란 선언이고 method는 POST request(data가 제출될것이라는 뜻)가 들어올것이다. (GET request라면 data가 return 될것이란 뜻이다)



{% csrf_token %}

이건 Cross Site Request Forgery라는 뜻인데 자세한건 찾아보아라: Cross-Site Request Forgery (CSRF).

간략하게 설명하자면 보안관련해서 내 정보가 위조되지 않게하는 기능이다.



이 페이지가 rendering 되면서 form이라는 변수가 context를 통해서 주어지게 할것이다.


view에서 render시키는 code를 만들를 아래와 같이 해보자.

등록 기능을 creationForm을 가져와 만든다.


mysite/main/views.py:

from django.contrib.auth.forms import UserCreationForm

def register(request): form = UserCreationForm return render(request = request, template_name = "main/register.html", context={"form":form})

자 이제 template만들었고 view도 만들었으니 controller작업만 남았다.


mysite/main/urls.py 가서 아래와 같이 path를 추가해 준다.

path("/register", views.register, name="register"),

전체 파일:

from django.urls import path
from . import views


app_name = 'main'  # here for namespacing of urls.

urlpatterns = [
  path("", views.homepage, name="homepage"),
  path("register/", views.register, name="register"),
]

이제 navbar에 있는 register를 클릭!

python tutorials

자 우선 너무 왼쪽 위 끝에 붙어있는데 이를 수정해보자

mysite/main/templates/main/header.html

...
  <div class="container">
    {% block content %}
    {% endblock %}
  </div>
...

register.html 에도 br 같은거 좀 줘서 위치를 조정해보자

{% extends 'main/header.html' %}

{% block content %}
    <br>
    <form method="POST">
        {% csrf_token %}
        {{form}}
    </form>

    If you already have an account <a href="/login" target="blank"><strong>login</strong></a> instead.

{% endblock %}

python tutorials


자 이제 제출 버튼을 추가

<button style="background-color:#F4EB16; color:blue" class="btn btn-outline-info" type="submit">Sign Up</button>

전체 mysite/main/templates/main/register page is:

{% extends 'main/header.html' %}

{% block content %}

    <div class="container">
        <form method="POST">
            {% csrf_token %}
            {{form.as_p}}

            <button style="background-color:#F4EB16; color:blue" class="btn btn-outline-info" type="submit">Sign Up</button>

        </form>

        If you already have an account <a href="/login" target="blank"><strong>login</strong></a> instead.
    </div>
{% endblock %}

form가 가질수있는 attributes는 다음과 같다.

  • as_p - paragraph tags
  • as_table - as a table
  • as_ul - as an unordered list

{% extends 'main/header.html' %} {% block content %} <br> <form method="POST"> {% csrf_token %} {{form.as_p}} <button style="background-color:#F4EB16; color:blue" class="btn btn-outline-info" type="submit">Sign Up</button> </form> If you already have an account <a href="/login" target="blank"><strong>login</strong></a> instead. {% endblock %}

python tutorials


이제 우리의 submit button을 누르면 POST request가 일어난다.

그럼 이를 처리하는 내용을 views.py에서 만들어줘야한다.


submit button을 누르고나면 그것이 Post인지 아닌지 아닌지 확인하고


    if request.method == "POST":

그 form의 내용을 가져와야한다.

        form = UserCreationForm(request.POST)

만약 내용이 있다면 form기능에서 제공하는 save기능을 수행

user = form.save()

이것은 user를 저장하게 되고 django.contrib.auth를 통해 인증과정을 통해 계속 로그인, 로그아웃등의 기능을 부여해줄수있다.

from django.contrib.auth import logout, authenticate, login

이를 통해 저장된 계정을 불러와 로그인 할수있다.:

            username = form.cleaned_data.get('username')
            login(request, user)

이제 django가 홈페이지로 유저정보를 유지하면서 이동해야 하는데 이는 render를 쓸수있긴 하지만 redirect를 사용하면 단순히 주어진 url로 정보를 보내고 온다.

from django.shortcuts import render, redirect

return redirect("main:homepage")

이렇게 하면 app_name='main'에서 url 에서 hompage로 안내된다.

def register(request): if request.method == "POST": form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() username = form.cleaned_data.get('username') login(request, user) return redirect("main:homepage") form = UserCreationForm return render(request = request, template_name = "main/register.html", context={"form":form})

혹시 form이 비어있을수도 있으니

이에대한 예외처리를 해준다.

def register(request):
    if request.method == "POST":
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            username = form.cleaned_data.get('username')
            login(request, user)
            return redirect("main:homepage")

        else:
            for msg in form.error_messages:
                print(form.error_messages[msg])

            return render(request = request,
                          template_name = "main/register.html",
                          context={"form":form})

    form = UserCreationForm
    return render(request = request,
                  template_name = "main/register.html",
                  context={"form":form})

이렇게 하고나면 다시 사용자를 등록할수도있고 등록하면 다시 homepage로 돌아온다.

from django.shortcuts import render, redirect from .models import Tutorial from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.contrib.auth import logout, authenticate, login # Create your views here. def homepage(request): return render(request = request, template_name='main/home.html', context = {"tutorials":Tutorial.objects.all}) def register(request): if request.method == "POST": form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() username = form.cleaned_data.get('username') login(request, user) return redirect("main:homepage") else: for msg in form.error_messages: print(form.error_messages[msg]) return render(request = request, template_name = "main/register.html", context={"form":form}) form = UserCreationForm return render(request = request, template_name = "main/register.html", context={"form":form})


'Backup > Django' 카테고리의 다른 글

[Django #8] User Login and Logout  (0) 2019.02.05
[Django #7] Messages  (0) 2019.02.05
[Django #5] CSS  (0) 2019.02.03
[Django #4] Views and Templates  (0) 2019.02.03
[Django #3] Admin and Apps  (1) 2019.02.02