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
복사
단축키 : Alt + Enter → import
Ctrl + B → 해당 위치 이동
reverse vs reverse_lazy : 함수 → reverse
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
복사