📢 공지사항
home

Section 2 (Accountapp implementation)

1. CreateView를 통한 회원가입 구현

학습 목표 : 장고에서 제공하는 CreateView를 통해 Account의 Create, 즉 회원 가입을 구현해 본다.
1) pragmatic/accountApp/views.py
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse, reverse_lazy from accountApp.models import HelloWorld from django.views.generic import CreateView def hello_world(request): # class-Based View로 AccountCreateView를 추가한다. class AccountCreateView(CreateView): model = User form_class = UserCreationForm success_url = reverse_lazy('accountApp:hello_world') # 계정 만들기 성공 했으면, 어느 경로로 연결할 것인가? template_name = 'accountApp/create.html' # 어느 html 파일을 통해서 볼지?
Python
복사
2) pragmatic/accountApp/urls.py
from django.urls import path from accountApp.views import hello_world, AccountCreateView app_name = "accountApp" urlpatterns = [ path('hello_world/', hello_world, name='hello_world'), # create 경로를 추가한다. path('create/', AccountCreateView.as_view(), name='create'), ]
Python
복사
3) pragmatic/accountApp/templates/accountApp/create.html (create.html 생성)
{% extends 'base.html' %} {% block content %} <div style="text-align: center"> <form action="{% url 'accountApp:create' %}" method="post"> <!-- post 사용 시, 잊지 말 것! --> {% csrf_token %} <!-- views.py에서 지정한 class form --> {{ form }} <input type="submit" class="btn btn-primary"> </form> </div> {% endblock %}
HTML
복사

2. Login / Logout 구현

학습 목표 : 장고에서 제공되는 LoginView, LogoutView를 기반으로 로그인 및 로그아웃 기능을 구현한다.
1) pragmatic/accountApp/urls.py
from django.urls import path from accountApp.views import hello_world, AccountCreateView from django.contrib.auth.views import LoginView, LogoutView app_name = "accountApp" urlpatterns = [ path('hello_world/', hello_world, name='hello_world'), # login과 logout 경로를 추가한다. path('login/', LoginView.as_view(template_name='accountApp/login.html'), name='login'), path('logout/', LogoutView.as_view(), name='logout'), path('create/', AccountCreateView.as_view(), name='create'), ]
Python
복사
2) pragmatic/accountApp/templates/accountApp/login.html (login.html 생성)
{% extends 'base.html' %} {% block content %} <div style="text-align: center"> <div> <h4>Login</h4> </div> <div> <form action="" method="post"> {% csrf_token %} {{ form }} <input type="submit" class="btn btn-primary"> </form> </div> </div> {% endblock %}
HTML
복사
3) pragmatic/pragmatic/templates/header.html
<div class="pragmatic_header"> <div> <h1 class="pragmatic_logo">Pragmatic</h1> </div> <div> <span>nav1</span> <span>nav2</span> <span>nav3</span> {% if not user.is_authenticated %} <!--유저가 로그인 되어 있지 않을 경우--> <a href="{% url 'accountApp:login' %}?next={{ request.path }}"> <span>login</span> </a> {% else %} <!--유저가 로그인 되어 있을 경우--> <a href="{% url 'accountApp:logout' %}?next={{ request.path }}"> <span>logout</span> </a> {%endif %} </div> </div>
HTML
복사
4) pragmatic/pragmatic/settings.py
from pathlib import Path import environ import os from django.urls import reverse_lazy # 맨 하단에 Redirect 경로를 추가한다. LOGIN_REDIRECT_URL = reverse_lazy('accountApp:hello_world') LOGOUT_REDIRECT_URL = reverse_lazy('accountApp:login')
Python
복사

3. Bootstrap을 이용한 Form 디자인 정리

학습 목표 : django-bootstrap4 라이브러리를 이용하여 form을 부트스트랩 스타일로 꾸며보고, 지금까지 만든 사이트의 디자인을 정리한다.
1) pragmatic/pragmatic/settings.py
우선, 터미널에서 pip install django-bootstrap4 입력하여 설치한다.
그 다음 settings.py에서 내용을 추가한다.
from pathlib import Path import environ import os from django.urls import reverse_lazy # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'accountApp', # 추가한다. 'bootstrap4', ]
Python
복사
2) pragmatic/accountApp/templates/accountApp/login.html
{% extends 'base.html' %} {% load bootstrap4 %} {% block content %} <!-- (문단의 스타일을 추가적으로 변경함) --> <div style="text-align: center; max-width: 500px; margin: 4rem auto"> <div> <h4>Login</h4> </div> <div> <form action="" method="post"> {% csrf_token %} <!-- 기존 {{ form }} 대신 bootstrap_form으로 변경한다.--> {% bootstrap_form form %} <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3"> </form> </div> </div> {% endblock %}
HTML
복사
3) pragmatic/accountApp/templates/accountApp/create.html
{% extends 'base.html' %} <!-- 추가한다. --> {% load bootstrap4 %} {% block content %} <!-- 변경한다. --> <div style="text-align: center; max-width: 500px; margin: 4rem auto"> <div class="mb-4"> <h4>SignUp</h4> </div> <form action="{% url 'accountApp:create' %}" method="post"> {% csrf_token %} {% bootstrap_form form %} <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3"> </form> </div> {% endblock %}
HTML
복사
4) pragmatic/templates/head.html (폰트를 전체적으로 변경하고 싶을 때)
우선, pragmatic/static 하단에 ‘fonts’라는 새 디렉토리를 생성한 후, 다운 받은 글꼴 파일을 삽입한다.
그 다음 head.html 파일에서 <style> 태그를 통해 내용을 추가한다.
{% load static %} <head> <meta charset="UTF-8"> <title>Pragmatic</title> <!-- 폰트 정보를 추가한다. --> <style> @font-face { font-family: 'NanumPen'; src: local('NanumPen'), url("{% static 'fonts/NanumPen.ttf' %}") format("opentype"); } </style> </head>
HTML
복사

4. DetailView를 이용한 개인 페이지 구현

학습 목표 : DetailView를 이용하여 개인 페이지를 만들어 본다.
1) pragmatic/pragmatic/views.py
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse, reverse_lazy # Create your views here. from accountApp.models import HelloWorld from django.views.generic import CreateView, DetailView def hello_world(request): class AccountCreateView(CreateView): # AccountDetailView 클래스를 추가한다. class AccountDetailView(DetailView): model = User context_object_name = 'target_user' template_name = 'accountApp/detail.html'
Python
복사
2) pragmatic/accountApp/templates/accountApp/detail.html (detail.html 생성)
{% extends 'base.html' %} {% block content %} <div> <div style="text-align: center; max-width: 500px; margin: 4rem auto;"> <p> {{ target_user.date_joined }} </p> <h2 style="font-family: 'NanumPen'"> {{ target_user.username }} </h2> </div> </div> {% endblock %}
HTML
복사
3) pragmatic/accountApp/urls.py
from django.contrib.auth.views import LoginView, LogoutView from django.urls import path from accountApp.views import hello_world, AccountCreateView, AccountDetailView app_name = "accountApp" urlpatterns = [ path('hello_world/', hello_world, name='hello_world'), path('login/', LoginView.as_view(template_name='accountApp/login.html'), name='login'), path('logout/', LogoutView.as_view(), name='logout'), path('create/', AccountCreateView.as_view(), name='create'), # detail 경로를 추가한다. path('detail/<int:pk>', AccountDetailView.as_view(), name='detail'), ]
Python
복사
3) pragmatic/templates/header.html
<div class="pragmatic_header"> <div> <h1 class="pragmatic_logo">Pragmatic</h1> </div> <div> <span>nav1</span> <span>nav2</span> <span>nav3</span> {% if not user.is_authenticated %} <!-- 유저가 로그인 되어 있지 않을 경우 --> {% else %} <!-- 유저가 로그인 되어 있을 경우 --> <!-- detail.html로 연결될 MyPage 바를 추가한다. --> <a href="{% url 'accountApp:detail' pk=user.pk %}"> <span>MyPage</span> </a> <a href="{% url 'accountApp:logout' %}?next={{ request.path }}"> <span>logout</span> </a> {%endif %} </div> </div>
HTML
복사

5. UpdateView를 이용한 비밀번호 변경 구현

학습 목표 : UpdateView를 이용한 비밀번호 변경 구현을 진행한다.
1) pragmatic/accountApp/views.py
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse, reverse_lazy from accountApp.models import HelloWorld from django.views.generic import CreateView, DetailView, UpdateView from accountApp.forms import AccountUpdateForm def hello_world(request): class AccountCreateView(CreateView): class AccountDetailView(DetailView): # AccountCreatView 클래스를 토대로 AccountUpdateView를 추가한다. class AccountUpdateView(UpdateView): model = User context_object_name = 'target_user' form_class = AccountUpdateForm # Form을 바꿔줌 success_url = reverse_lazy('accountApp:hello_world') template_name = 'accountApp/update.html'
Python
복사
2) pragmatic/accountApp/urls.py
from django.contrib.auth.views import LoginView, LogoutView from django.urls import path from accountApp.views import hello_world, AccountCreateView, AccountDetailView, AccountUpdateView app_name = "accountApp" urlpatterns = [ path('hello_world/', hello_world, name='hello_world'), path('login/', LoginView.as_view(template_name='accountApp/login.html'), name='login'), path('logout/', LogoutView.as_view(), name='logout'), path('create/', AccountCreateView.as_view(), name='create'), path('detail/<int:pk>', AccountDetailView.as_view(), name='detail'), # update 경로를 추가한다. path('update/<int:pk>', AccountUpdateView.as_view(), name='update'), ]
Python
복사
3) pragmatic/accountApp/templates/accountApp/update.html (update.html 생성)
<!-- create.html 내용을 토대로 작성함 --> {% extends 'base.html' %} {% load bootstrap4 %} {% block content %} <div style="text-align: center; max-width: 500px; margin: 4rem auto"> <div class="mb-4"> <h4>Change Info</h4> </div> <form action="{% url 'accountApp:update' pk=target_user.pk %}" method="post"> {% csrf_token %} {% bootstrap_form form %} <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3"> </form> </div> {% endblock %}
HTML
복사
4) pragmatic/accountApp/templates/accountApp/detail.html
{% extends 'base.html' %} {% block content %} <div> <div style="text-align: center; max-width: 500px; margin: 4rem auto;"> <p> {{ target_user.date_joined }} </p> <h2 style="font-family: 'NanumPen'"> {{ target_user.username }} </h2> <!-- 로그인 했을 경우, 변경하고자 하는 유저가 본인일 경우 update 가능 (추가) --> {% if target_user == user %} <a href="{% url 'accountApp:update' pk=user.pk %}"> <p> Change Info </p> </a> {% endif %} </div> </div> {% endblock %}
HTML
복사
5) pragmatic/accountApp/forms.py (forms.py 생성)
# update 시, id 변경을 비활성화 하기 위한 용도 from django.contrib.auth.forms import UserCreationForm class AccountUpdateForm(UserCreationForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['username'].disabled = True
Python
복사

6. DeleteView 기반 회원 탈퇴 구현

학습 목표 : DeleteView 기반 회원 탈퇴 구현을 진행한다.
1) pragmatic/accountApp/views.py
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse, reverse_lazy from accountApp.models import HelloWorld from django.views.generic import CreateView, DetailView, UpdateView, DeleteView from accountApp.forms import AccountUpdateForm def hello_world(request): class AccountCreateView(CreateView): class AccountDetailView(DetailView): class AccountUpdateView(UpdateView): # AccountDeleteView를 추가한다. class AccountDeleteView(DeleteView): model = User context_object_name = 'target_user' success_url = reverse_lazy('accountApp:login') template_name = 'accountApp/delete.html'
Python
복사
2) pragmatic/accountApp/urls.py
from django.contrib.auth.views import LoginView, LogoutView from django.urls import path from accountApp.views import hello_world, AccountCreateView, AccountDetailView from accountApp.views import AccountUpdateView, AccountDeleteView app_name = "accountApp" urlpatterns = [ path('hello_world/', hello_world, name='hello_world'), path('login/', LoginView.as_view(template_name='accountApp/login.html'), name='login'), path('logout/', LogoutView.as_view(), name='logout'), path('create/', AccountCreateView.as_view(), name='create'), path('detail/<int:pk>', AccountDetailView.as_view(), name='detail'), path('update/<int:pk>', AccountUpdateView.as_view(), name='update'), # delete 경로를 추가한다. path('delete/<int:pk>', AccountDeleteView.as_view(), name='delete'), ]
Python
복사
3) pragmatic/accountApp/templates/accountApp/delete.html (delete.html 생성)
{% extends 'base.html' %} {% block content %} <div style="text-align: center; max-width: 500px; margin: 4rem auto"> <div class="mb-4"> <h4>Quit</h4> </div> <form action="{% url 'accountApp:delete' pk=target_user.pk %}" method="post"> {% csrf_token %} <input type="submit" class="btn btn-danger rounded-pill col-6 mt-3"> </form> </div> {% endblock %}
HTML
복사
4) pragmatic/accountApp/templates/accountApp/detail.html
{% extends 'base.html' %} {% block content %} <div> <div style="text-align: center; max-width: 500px; margin: 4rem auto;"> <p> {{ target_user.date_joined }} </p> <h2 style="font-family: 'NanumPen'"> {{ target_user.username }} </h2> {% if target_user == user %} <a href="{% url 'accountApp:update' pk=user.pk %}"> <p> Change Info </p> </a> <!-- Quit이 가능한 경우를 추가해 준다. --> <a href="{% url 'accountApp:delete' pk=user.pk %}"> <p> Quit </p> </a> {% endif %} </div> </div> {% endblock %}
HTML
복사
3) pragmatic/templates/header.html
<div class="pragmatic_header"> <div> <h1 class="pragmatic_logo">Pragmatic</h1> </div> <div> <span>nav1</span> <span>nav2</span> <span>nav3</span> {% if not user.is_authenticated %} <!-- 유저가 로그인 되어 있지 않을 경우 --> <a href="{% url 'accountApp:login' %}?next={{ request.path }}"> <span>login</span> </a> <a href="{% url 'accountApp:create' %}"> <span>SignUp</span> </a> {% else %} <!-- 유저가 로그인 되어 있을 경우 --> <a href="{% url 'accountApp:detail' pk=user.pk %}"> <span>MyPage</span> </a> <a href="{% url 'accountApp:logout' %}?next={{ request.path }}"> <span>logout</span> </a> {%endif %} </div> </div>
HTML
복사