• 인프런의 이진석 강사님의 강의를 참고

로그인처리를 위한 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

BELATED ARTICLES

more