02. Accountapp Implentation
02. Accountapp Implentation
 21강_CreateView를 통한 회원가입 구현
•
pragmatic\accountapp\templates\views.py
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 django.views.generic import CreateView
from accountapp.models import HelloWorld
def hello_world(request):
	if request.method == "POST":
		 # temp : 받은 data를 그대로 보내는 작업
		 temp = resquest.POST.get('hello_world_input')
		 
	   # DB에 data 저장
		 new_hello_world = HelloWorld()
	   new_hello_world.text = temp
	   new_hello_world.save()
		 return HttpResponseRedirect(reverse('accountapp:hello_world'))
	
	else :
		 hello_world_list = HelloWorld.objects.all()
		 return render(request, 'accountapp\helloworld.html', context = {'hello_world_list' : hello_world_output})
class AccountCreateView(CreateView):
		model = User
		form_class = UserCreationForm   # Account에 대해 Django가 제공하는 기본적인 틀
		success_url = reverse_lazy('accountapp:hello_world')
		template_name = 'accountapp/create.html'
Python
복사
                   Ctrl + B → 해당 위치 이동
                                             class → reverse_lazy
•
pragmatic\accountapp\templates\urls.py
from django.urls import path
from accountapp.views import hello_world
app_name = "accountapp"
urlpatterns = [
    path('hello_world/', hello_world, name = 'hello_world'),
    path('create/', AccountCreateView.as_view(), name = 'create'),
]
Python
복사
•
pragmatic\accountapp\templates\accountapp\create.html
{% extends 'base.html' %}
{% block content %}
<div style = "text-align : center;">
	<form action = "{% url 'accountapp:create' %}" method = "post">
		{% crsf_token %}
		{{ form  }}
		<input type = "submit" class = "btn btn-primary">
	</form>
</div>
HTML
복사
 22강_Login / Logout 구현
•
Django에서 기본적으로 제공해주는 View
◦
Login View
◦
Logout View
•
urls.py
path('login/', LoginView.as_view(template_name = 'accountapp/login.html'), name='login'),
path('logout/', LoginView.as_view(), name='logout'),
Python
복사
•
login.html
{% extends 'base.html' %}
{% block content %}
	<div style = "text-align : center">
		<div>
				<h4>Login</h4>
						<form action = "" method = "post">
								{% dsrf_token %}
								{{ form }}
								<input type = "submit" class = "btn btn-primary">
						</form>
		</div>
	</div>
Python
복사
•
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>
Python
복사
•
settings.py
LOGIN_REDIRECT_URL = reverse_laxy('accountapp:hello_world')
LOGOUT_REDIRECT_URL = reverse_laxy('accountapp:login')
Python
복사
 23강_Bootstrap을 이용한 Form 디자인 정리
 24강_DetailView를 이용한 개인 페이지 구현
•
views.py
class AccountDetailView(DetailView):
		model = User
		template_name = 'accountapp/detail.html'
Python
복사
•
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 : 'NanumSquareB'">
					{{ target_user.username }}
				</h2>
		</div>
	</div>
{% endblock %}
Python
복사
•
urls.py
path('create/', AccountCreateView.as_view(), name='create'),
path('detail/<int:pk>', AccountDetailView.as_view(), name='detail'),
Python
복사
•
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:detail' pk = user.pk %}">
				<span>MyPage<\span>
		<\a>
		{% else %}
		<a href = "{% url 'accountapp:login' %}?next = {{ request.path }}">
				<span>login<\span>
		<\a>
		<a href = "{% url 'accountapp:logout' %}?next = {{ request.path }}">
				<span>logout<\span>
		<\a>
	{% endif %}
	</div>
</div>
Python
복사
•
views.py
class AccountDetailView(DetailView):
		model = User
		context_object_name = 'target_user'
		template_name = 'accountapp/detail.html'
Python
복사
 25강_UpdateView를 이용한 비밀번호 변경 구현
•
views.py
class AccountUpdateView(UpdateView):
		model = User
		form_class = UserCreationForm
		success_url = 'target_user'
		template_name = 'accountapp/update.html'
Python
복사
•
urls.py
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'),
Python
복사
•
update.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 = user.pk %}" method = "post">
		{% crsf_token %}
		{{ form  }}
		<input type = "submit" class = "btn btn-dark rounded-pill col-6 mt-3">
	</form>
</div>
{% endblock %}
Python
복사
•
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 : 'NanumSquareB'">
					{{ target_user.username }}
				</h2>
		{% if target_user == user %}
		<a href = "{% url 'accountapp:update' pk = user.pk %}">
			<p>
				Change Info
			</p>
		</a>
		{% endif %}
		</div>
	</div>
{% endblock %}
Python
복사
•
form.py
from django.contrib.auth.forms import UserCreationForm
class AccountUpdateForm(UserCreationForm):
	def __init__(self, *args, **kwargs):
			super().__init__(*args, **kwargs)
			seflf.fields['username'].disabled = True
Python
복사
•
views.py
class AccountUpdateView(UpdateView):
		model = User
		form_class = AccountUpdateForm
		success_url = reverse_lazy('accountapp:hello_world')
		template_name = 'accountapp/update.html'
Python
복사
 26강_DeleteView기반 회원 탈퇴 구현
•
views.py
class AccountDeleteView(UpdateView):
		model = User
		success_url = reverse_lazy('accountapp:login')
		template_name = 'accountapp/delete.html'
Python
복사
•
urls.py
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'),
path('update/int:pk>', AccountDeleteView.as_view(), name = 'delete'),
Python
복사
•
delete.html
{% extends 'base.html' %}
{% load bootstrap4 %}
{% 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:update' pk = user.pk %}" method = "post">
		{% crsf_token %}
		{{ form  }}
		<input type = "submit" class = "btn btn-danger rounded-pill col-6 mt-3">
	</form>
</div>
{% endblock %}
Python
복사
•
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 : 'NanumSquareB'">
					{{ target_user.username }}
				</h2>
		{% if target_user == user %}
		<a href = "{% url 'accountapp:update' pk = user.pk %}">
			<p>
				Change Info
			</p>
		</a>
		<a href = "{% url 'accountapp:delete' pk = user.pk %}">
			<p>
				Quit
			</p>
		</a>
		{% endif %}
		</div>
	</div>
{% endblock %}
Python
복사
•
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:detail' pk = user.pk %}">
				<span>login<\span>
		<\a>
		<a href = "{% url 'accountapp:create' %}">
				<span>SignUp<\span>
		<\a>
		{% else %}
		<a href = "{% url 'accountapp:login' %}?next = {{ request.path }}">
				<span>MyPage<\span>
		<\a>
		<a href = "{% url 'accountapp:logout' %}?next = {{ request.path }}">
				<span>logout<\span>
		<\a>
	{% endif %}
	</div>
</div>
Python
복사
03. Authentication
03. Authentication
 27강_Authentication 인증시스템 구축
•
urls.py
def hello_world(request):
    if request.user.is_authenticated: #추가! 로그인이 되어있으면 기존처럼
        if request.method == "POST":
            temp = request.POST.get('hello_world_input')
            new_hello_world = HelloWorld()
            new_hello_world.text = temp
            new_hello_world.save()
            return HttpResponseRedirect(reverse('accountapp:hello_world'))
        else:
            hello_world_list = HelloWorld.objects.all()
            return render(request, 'accountapp/hello_world.html', context={'hello_world_list': hello_world_list})
    else:
        return HttpResponseRedirect(reverse('accountapp:login'))
Python
복사
 28강_Decorator를 이용한 소스 간소화
•
view.py
@login_required
@method_decorator(login_required, 'get')
@method_decorator(login_required, 'post')
..
.
.
Python
복사
•
decorator.py
def account_ownership_required(func):
    def decorated(request, *args, **kwargs):
        user = User.objects.get(pk=kwargs['pk'])
        if not user == request.user:
            return HttpResponseForbidden()
        return func(request, *args, **kwargs)
    return decorated
Python
복사
•
views.py
has_ownership = [account_ownership_required, login_required]
Python
복사
 29강_superuser, media 관련 설정
•
SuperUser
•
media
 22강_Login / Logout 구현
•
Django에서 기본적으로 제공해주는 View
◦
Login View
◦
Logout View
•
urls.py
path('login/', LoginView.as_view(template_name = 'accountapp/login.html'), name='login'),
path('logout/', LoginView.as_view(), name='logout'),
Python
복사
•
login.html
{% extends 'base.html' %}
{% block content %}
	<div style = "text-align : center">
		<div>
				<h4>Login</h4>
						<form action = "" method = "post">
								{% dsrf_token %}
								{{ form }}
								<input type = "submit" class = "btn btn-primary">
						</form>
		</div>
	</div>
Python
복사
•
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>
Python
복사
•
settings.py
LOGIN_REDIRECT_URL = reverse_laxy('accountapp:hello_world')
LOGOUT_REDIRECT_URL = reverse_laxy('accountapp:login')
Python
복사
 23강_Bootstrap을 이용한 Form 디자인 정리
 24강_DetailView를 이용한 개인 페이지 구현
•
views.py
class AccountDetailView(DetailView):
		model = User
		template_name = 'accountapp/detail.html'
Python
복사
•
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 : 'NanumSquareB'">
					{{ target_user.username }}
				</h2>
		</div>
	</div>
{% endblock %}
Python
복사
•
urls.py
path('create/', AccountCreateView.as_view(), name='create'),
path('detail/<int:pk>', AccountDetailView.as_view(), name='detail'),
Python
복사
•
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:detail' pk = user.pk %}">
				<span>MyPage<\span>
		<\a>
		{% else %}
		<a href = "{% url 'accountapp:login' %}?next = {{ request.path }}">
				<span>login<\span>
		<\a>
		<a href = "{% url 'accountapp:logout' %}?next = {{ request.path }}">
				<span>logout<\span>
		<\a>
	{% endif %}
	</div>
</div>
Python
복사
•
views.py
class AccountDetailView(DetailView):
		model = User
		context_object_name = 'target_user'
		template_name = 'accountapp/detail.html'
Python
복사
 25강_UpdateView를 이용한 비밀번호 변경 구현
•
views.py
class AccountUpdateView(UpdateView):
		model = User
		form_class = UserCreationForm
		success_url = 'target_user'
		template_name = 'accountapp/update.html'
Python
복사
•
urls.py
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'),
Python
복사
•
update.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 = user.pk %}" method = "post">
		{% crsf_token %}
		{{ form  }}
		<input type = "submit" class = "btn btn-dark rounded-pill col-6 mt-3">
	</form>
</div>
{% endblock %}
Python
복사
•
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 : 'NanumSquareB'">
					{{ target_user.username }}
				</h2>
		{% if target_user == user %}
		<a href = "{% url 'accountapp:update' pk = user.pk %}">
			<p>
				Change Info
			</p>
		</a>
		{% endif %}
		</div>
	</div>
{% endblock %}
Python
복사
•
form.py
from django.contrib.auth.forms import UserCreationForm
class AccountUpdateForm(UserCreationForm):
	def __init__(self, *args, **kwargs):
			super().__init__(*args, **kwargs)
			seflf.fields['username'].disabled = True
Python
복사
•
views.py
class AccountUpdateView(UpdateView):
		model = User
		form_class = AccountUpdateForm
		success_url = reverse_lazy('accountapp:hello_world')
		template_name = 'accountapp/update.html'
Python
복사
 26강_DeleteView기반 회원 탈퇴 구현
•
views.py
class AccountDeleteView(UpdateView):
		model = User
		success_url = reverse_lazy('accountapp:login')
		template_name = 'accountapp/delete.html'
Python
복사
•
urls.py
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'),
path('update/int:pk>', AccountDeleteView.as_view(), name = 'delete'),
Python
복사
•
delete.html
{% extends 'base.html' %}
{% load bootstrap4 %}
{% 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:update' pk = user.pk %}" method = "post">
		{% crsf_token %}
		{{ form  }}
		<input type = "submit" class = "btn btn-danger rounded-pill col-6 mt-3">
	</form>
</div>
{% endblock %}
Python
복사
•
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 : 'NanumSquareB'">
					{{ target_user.username }}
				</h2>
		{% if target_user == user %}
		<a href = "{% url 'accountapp:update' pk = user.pk %}">
			<p>
				Change Info
			</p>
		</a>
		<a href = "{% url 'accountapp:delete' pk = user.pk %}">
			<p>
				Quit
			</p>
		</a>
		{% endif %}
		</div>
	</div>
{% endblock %}
Python
복사
•
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:detail' pk = user.pk %}">
				<span>login<\span>
		<\a>
		<a href = "{% url 'accountapp:create' %}">
				<span>SignUp<\span>
		<\a>
		{% else %}
		<a href = "{% url 'accountapp:login' %}?next = {{ request.path }}">
				<span>MyPage<\span>
		<\a>
		<a href = "{% url 'accountapp:logout' %}?next = {{ request.path }}">
				<span>logout<\span>
		<\a>
	{% endif %}
	</div>
</div>
Python
복사
 29강_superuser, media 관련 설정
•
SuperUser
•
media
04. Profileapp Implementation
04. Profileapp Implementation
 30강_Profileapp 시작 그리고 ModelForm
•
Account 
 Profile ⇒ 1 : 1
•
models,py
class Profile(modles.Model)"
	user = models.OneToOneField(User, on_delete = models.CASCADE, related_name = 'profile')
	image = modles.ImageField(upload_to = 'profile/', null = True)
	nickname = modles.CharFiled(max_length = 20, unique = True, null = True)
	message = models.CharField(max_length = 100, null = True)
Python
복사
•
forms.py
from django.forms import ModelForm
from profileapp.models import Profile
class ProfileCreationForm(ModelForm):
    class Meta:
        model = Profile
        fields = ['image', 'nickname', 'message']
Python
복사
