로그인처리(LoginView) , 프로필 수정 // 장고 기본인증(1)
2022. 4. 19. 01:59
- 인프런의 이진석 강사님의 강의를 참고
로그인처리를 위한 LoginView
- 장고는 로그인 기능을 위한 LoginView를 제공함. 아래는 사용예시
#urls.py
from django.contrib. auth.views import LoginView
from django.urls import path
urlpatterns =[
path('login/',LoginView.as_view(template_name='accounts/login_form.html'),name='login'),
]
- Loginview는 기본적으로 장고에서 제공하는 Authentication Form을 사용한다
- 링크 : https://github.com/django/django/blob/main/django/contrib/auth/views.py#L49
- Authentication Form을 사용하기에 자동으로 템플릿만 지정해주면, 해당 템플릿에 아이디와 비번을 입력할 빈Form을 제공하고, 유저가 해당 Form에 값을 넣어서 전송하려 할 경우 자동으로 유효성검사까지 진행해 준다.
- 폼이 제공하는 기능이 어디까지인지를 인지하고 필요한 부분을 추가하는 것이 매우 중요!
로그인 후의 페이지 이동
- 로그인 페이지에서 url 쿼리스트링에 next인자가 있으면, next인자의 값으로 이동함
- 만약 next인자값이 없으면 settings.LOGIN_REDIRECT_URL에 입력된 값으로 이동함.
- 해당 설정값의 기본 default는 '/accounts/profile/'
- 즉 별다른 설정을 안해주고 next인자가 없으면, 로그인 처리후에 /accounts/profile로 이동함
- 참고)settings.LOGIN_URL : login_required 데코레이터나 믹스인이 사용되어서, 로그인이 필요할 경우 설정된 LOGIN_URL에 설정된 값으로 이동
로그인을 위한 항목 추가
- 유효성검사를 실행하는 form의 기능을 활용해 , 로그인에 필요한 항목을 추가할 수 있다.
- 앞서 언급했 듯, 장고에서 로그인 기능을 사용하기 위해 장고의 Loginview를 사용하고 Loginview는 내부적으로 Authentication form을 사용한다
- 그러면 Authentication form을 상속받아서 로그인을 위한 추가질문 필드를 만들어주고, loginview에서 사용할 form으로 넘겨줌으로써 로그인을 위한 항목을 추가할 수 있다.
- 아래의 예시에서는 form의 'clean_필드명' 함수 기능을 사용했다
- Loginview는 내부적으로 form을 활용해 유효성 검사를 실행하는데, 유효성 검사를 실행하고 나서 form인스턴스에 'clean_필드명' 함수가 존재할 경우, 해당함수를 실행한다.
- 유효성 검사나 clean_필드명 함수 등을 통한 검사에서 한 개의 필드라도 실패할 경우 요청은 서버에서 승인되지 않는다. 즉, clean_awnser에서 원하는 대답인 6을 내놓지 않을 경우, 로그인 요청은 Loginview가 내부적으로 거절하여 실패하게 된다.
#forms.py
from django import forms
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
awnser = forms.IntegerField(help_text="3+3=?")
def clean_awnser(self):
awnser = self.cleaned_data.get('awnser')
if awnser != 6:
raise forms.ValidationError("땡~!")
return awnser
#urls.py
from django.contrib. auth.views import LoginView
from .forms import LoginForm
urlpatterns =[
path('login/',LoginView.as_view(template_name='accounts/login_form.html',form_class=LoginForm),name='login'),
]
- form_class로 forms.py에서 커스터마이징한 Loginform을 주는 모습
LogoutView(로그아웃)
- 로그아웃을 위해 LogoutView를 사용하면 됨
- 로그아웃 후 자동으로 이동할 페이지를 설정해주지 않으면 admin에서 로그아웃한 페이지로 이동하게 됨(즉 로그아웃 후에 이동할 페이지를 설정해 줘야 한다)
- Logoutview에 next_page라는 인자값을 주며, 해당 인자는 패턴네임(url reverse)을 사용할 수 있다
- next_page인자값을 따로 설정해주지 않을 경우, next_page = settings.LOGOUT_REDIRECT_VIEW이 됨
- 근데 settings.LOGOUT_REDIRECT_VIEW의 default는 None임. 즉 next_page든 LOGOUT_REDIRECT_VIEW이든 값을 설정해줘야 한다.(강사님은 LOGOUT_REDIRECT_VIEW의 값을 설정해주는 걸 추천하심)
- template의 경우, next인자값을 주는 방식으로 로그아웃 후의 페이지를 설정해줄 수도 있다.
#urls.py
#logoutview의 인자로 next_page를 주는 경우
from django.contrib. auth.views import LogoutView
from django.urls import path
urlpatterns =[
path('logout/',LogoutView.as_view(next_page='login'),name='logout'),
]
#template.html
#템플릿에 next인자를 주는 경우
<a href ="{% url 'logout' %}?next={{ request.get_full_path }}">
<h6>로그아웃</h6>
</a>
Profile Model 생성
- 프로필은 user와 one to one관계임
- USER모델을 사용하려면 conf.settings에 설정된 AUTH_USER_MODEL을 사용해야 한다!
#models.py
from django.db import models
from django.conf import settings
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
address = models.CharField(max_length=100,blank=True)
zipcode = models.CharField(max_length=6,blank = True)
Profile Model View
- Profile을 보여주는 CBV기반의 ProfileVIew를 구현
- Profile의 생성 및 수정을 담당하는 FBV기반의 profile_edit 구현
- 우선 profile이 있을 수도 있고 없을 수도 있으므로 try문을 사용. user.profile을 가져오는데, 없으면 Profile.DoesnotExist에러가 발생함. 그러면 profile을 none으로 준다.
- form에서 user_id에 대한 정보를 받지 않으므로, view단에서 처리하기 위해 save(commit=False)를 주고 user정보를 입력해줌
- 생성되는 form객체는 instacne=profile을 준다. 만약 user의 profile이 없다면 profile=none이므로 form객체도 아무런 값이 없는 빈form이 된다.
#views.py
#Profile을 보여줌
class ProfileView(LoginRequiredMixin,TemplateView):
template_name='accounts/profile.html'
profile=ProfileView.as_view()
#Profile의 생성과 수정을 담당
@login_required
def profile_edit(request):
try:
profile = request.user.profile
except Profile.DoesNotExist:
profile = None
if request.method == 'POST':
form = ProfileForm(request.POST,instance=profile)
if form.is_valid():
profile = form.save(commit=False)
profile.user = request.user
profile.save()
return redirect('profile')
else:
form = ProfileForm(instance=profile)
return render(request,'accounts/profile_form.html',{
"form":form
})
'django > basic' 카테고리의 다른 글
장고 에러 모음집 (0) | 2022.04.23 |
---|---|
회원가입,로그아웃 // 장고 기본인증(2) (0) | 2022.04.19 |
Generic editing views // Forms(6) (0) | 2022.04.18 |
Form validation : django form(5) (0) | 2022.04.17 |
CSRF 공격&CSRF Token // django form(4) (0) | 2022.04.17 |