21강CreateView를 통한 회원가입 구현
views.py에서
class AccountCreateView(CreateView):
model = User
form_class = UserCreationForm
success_url = reverse_lazy(’accountapp:hello_world’)
template_name = ‘accountapp/create.html’
reverse : 함수형 뷰에서 사용
reverse_lazy : 클래스형 뷰에서 사용
urls.py에서 (클래스 뷰일때)
path('create/', AccountCreateView.as_view(), name='create'),
]
create.html에서
{% extends 'base.html' %}
{% block content %}
<div style="text-align: center">
<form action="{% url 'accountapp:create' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="'submit" class="btn btn-primary">
</form>
</div>
{% endblock %}
22강 Login/Logout 구현
urls.py에서
path('login/',LoginView.as_view(template_name='accountapp/login.html'), name='login'),
path('logout/',LogoutView.as_view(), name='logout'),
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 %}
Redirect Mechanism?
next → LOGIN_REDIRECT_URL → Default
로그인 창 만들기
tamplates→header.html에서
{% 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 %}
pragmatic→settings.py에서
LOGIN_REDIRECT_URL = reverse_lazy('accountapp:hello_world')
LOGOUT_REDIRECT_URL = reverse_lazy('accountapp:hello_world')
23강 Bootstrap을 이용한 Form 디자인 정리
terminal에 pip install django-bootstrap4
→setting.py에서 INSTALLED_APPS에 ‘bootstrap4’,
→login.html→ {% load bootstrap4 %}→ {{form}}대신
{% bootstrap_form form %}사용→<div style="text-align: center; max-width: 500px; margin: 4rem auto">→ <input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
→create.html→{% load bootstrap4 %}→ {{form}}대신
{% bootstrap_form form %}사용→<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">→<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">→<div style="text-align: center; max-width: 500px; margin: 4rem auto">
→<div class="mb-4"> → 글꼴 파일 다운→ static에 fonts 폴더 생성→ 붙여넣기→templates→ head
<h4>SignUp</h4>
</div>
→<style>
@font-face {
font-family: 'NanumSquareR';
src: local('NanumSquareR'),
url("{% static 'fonts/NanumSquareR.ttf' %}") format("opentype");
}
@font-face {
font-family: 'NanumSquareEB';
src: local('NanumSquareEB'),
url("{% static 'fonts/NanumSquareEB.otf' %}") format("opentype");
}
@font-face {
font-family: 'NanumSquareB';
src: local('NanumSquareB'),
url("{% static 'fonts/NanumSquareB.otf' %}") format("opentype");
}
@font-face {
font-family: 'NanumSquareR';
src: local('NanumSquareR'),
url("{% static 'fonts/NanumSquareR.otf' %}") format("opentype");
}
</style>
→base.html에서 <body style="font-family: 'NanumSquareR';">
→base.css에서
.pragmatic_footer_button {
font-size: 0.9rem;
}
*mt-3 : margin top 크기 3배
mb-4 : margin bottom의 4배
col-6 : 너비 12=100%
24강 DetailView를 이용한 개인 페이지 구현
detail view
view.py→ class AccountDetailView(DetailView):
model = User
context_object_name = 'target_user'
template_name = 'accountapp/detail.html'
→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: 'NanumSquareB'">
{{ target_user.username }}
</h2>
</div>
</div>
{% endblock %}
→urls.py→ path('detail/<int:pk>', AccountDetailView.as_view(), name='detail'),
→header.html→<a href="{% url 'accountapp:detail' pk=user.pk %}">
<span>MyPage</span>
25장 UpdateView를 이용한 비밀번호 변경 구현
views.py→
class AccountUpdateView(UpdateView):
model = User
form_class =UserCreationForm
success_url = reverse_lazy('accountapp:hello_world')
template_name = 'accountapp/update.html'
→urls.py→
path('update/<int:pk>', AccountUpdateView.as_view(), name='update'),
→update.html (create랑 같음) →
{% 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">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
</form>
</div>
{% endblock %}
→detail.html→
{% if target_user == user %}
<a href=”{% url ‘accountapp:update’ pk=user.pk % }”>
<p>
Change Info
</p>
</a>
{% endif %}
→forms파일 만듬→
from django.contrib.auth.forms import UserCreationForm
class AccountUpdateForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].disabled = True
→views.py→ form_class = AccountUpdateForm
26강 DeleteView 기반 회원탈퇴 구현
view.py→
class AccountDeleteView(DeleteView):
model = User
success_url = reverse_lazy('accountapp:login')
template_name = 'accountapp/delete.html'
→urls.py→path('delete/<int:pk>', AccountDeleteView.as_view(), name='delete'),
→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=user.pk %}" method="post">
{% csrf_token %}
<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
</form>
</div>
{% endblock %}
→detail.py→
<a href="{% url 'accountapp:delete' pk=user.pk %}">
<p>
Quit
</p>
</a>
→delte.html→
<input type="submit" class="btn btn-danger rounded-pill col-6
내비게이션바에 회원가입 만들기
header.html→
<a href="{% url 'accountapp:create' %}">
<span>SignUp</span>
</a>
버그fix
→views.py→ context_object_name = 'target_user' 추가
(updatview, deleteview에 추가)
→delte.html, update.html→ pk=target_user.pk %로 바꾸기
→urls.py→path(’accounts/’, ~~~~~~~~~~~~)로 바꾸기
27강 Authentication 인증시스템 구축
28강 Decorator를 이용한 코드 간소화
Decorator : 함수 앞뒤에 붙어서 꾸며주는 기능
@login_required : 로그인 여부 확인&return 구문 해줌
@method_decorator() : 일반 function에 사용하는 decorator를 method에 사용할 수 있도록 변환
@method_decorator(login_required, 'get')
@method_decorator(login_required, 'post')
(updateview,deleteview에 적용)
from django.contrib.auth.models import User (user가져옴)
from django.http import HttpResponseForbidden (HttpResponseForbidden가져옴)
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
→views.py→
has_ownership = [account_ownership_required, login_required]
→@method_decorator(has_ownership, 'get')
@method_decorator(has_ownership, 'post')
29강 superuser, media 관련 설정
•
superuser
•
media
settings.py→
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
→ terminal→ pip install pillow
30강 Profileapp 시작, 그리고 ModelForm
•
profileapp
python manage.py startapp profileapp → settings.py → INSTALLED_APPS에 ‘profileapp’, →urls.py→ path('profiles/', include('profileapp.urls')), → profile에 urls.py 파일 만들기→
app_name= ‘profileapp‘
urlpatterns = [
]
→ profileapp/models.py→
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
image = models.ImageField(upload_to='profile/', null=True)
nickname = models.CharField(max_length=20, unique=True,null=True)
message = models.CharField(max_length=100, null=True)
•
form → model form 사용
profile에 forms.py파일 만듬→
class ProfileCreationForm(ModelForm):
class Meta:
model = Profile
fields = ['image', 'nickname', 'message']