[Django] 비 SPA 방식으로 장고 Forms/Views를 적극 활용한 인스타그램 St 만들기#4_로그인/로그아웃 구현 그리고 회원 가입과 동시에 로그인

아직·2022년 7월 11일
0
post-thumbnail

1)

urlpatterns =[
    path('login/', views.login, name='login')

앞서 @login_required 장식자를 이용했을 떄 /accounts/login/으로 이동했는데 이는 settings의 LOGIN_URL이 해당 문자열로 돼있는 설정값 때문이다.

2)

login = LoginView.as_view(template_name="accounts/login_form.html")

def signup(request):
    if request.method == 'POST':
...         
    else:
        form = SignupForm()
+
class View:
    """
    Intentionally simple parent class for all views. Only implements
    dispatch-by-method and simple sanity checking.
    """

    http_method_names = [
        "get",
        "post",
        "put",
        "patch",
        "delete",
        "head",
        "options",
        "trace",
    ]

    def __init__(self, **kwargs):
        """
        Constructor. Called in the URLconf; can contain helpful extra
        keyword arguments, and other things.
        """
        # Go through keyword arguments, and either save their values to our
        # instance, or raise an error.
        for key, value in kwargs.items():
            setattr(self, key, value)
            
    @classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""

accounts의 urls.py에서 login/, singup/ 으로 접근하면 각각 views의 login(인스턴스 함수?)와 signup(함수)를 보여주도록 안내한다. as_views는 class method로서 호출 시에 새로운 함수를 생성하여 반환한다.

signup은 User모델을 Meta적으로 따르고 email, first_name, last_name을 커스텀한 SignupForm에 의해 form 인스턴스를 생성한다.(form = SignupForm())

이 form은 'form'이라는 이름으로 accounts/signup_form.html에 전달돼서 {{ bootstrap_form form }} 형식으로 표현된다.

LoginView로 생성된 인스턴스 함수 login은 accounts/login_form.html으로 '자체적으로 생성된 form'을 넘겨준다. 이 역시 {{ bootstrap_form form }}에 적용되겠지만, 이는 signup에서와는 다른 form이다. 가령 LoginView-> FormView -> BaseFormView -> ProcessFormView에서 form을 생성함을 확인할 수 있다. 그런데 template_name에 form을 넘기는 부분은 더 확인해봐야 한다.

(signup에서와 달리) forms.py에 form field를 정의하지 않아도 되는 까닭은 LoginView-> FormView -> FormMixin의 함수 get_form_class와 get_form 부분이 AuthenticationForm을 참조하기 때문인 것 같다. 이때 (내 생각하기에) 가장 큰 차이점은 forms.py 파일에서 Model을 Meta적으로 참조하는 부분이 없다는 것이다.

그러나 class AuthenticationForm(forms.Form): 부분이 있는 걸 봤을 때 우리가 보는 forms.py와만 관련이 없을 뿐이지, 장고 내부적인 메커니즘의 forms.py는 참조하게 되어있는 것 같다.

결론적으로 ModelForm도 forms.Form을 기반으로 하고 View 내부적인 form 생성도 forms.Form을 기반으로 한다.

3)

class LogoutView(RedirectURLMixin, TemplateView):
    """
    Log out the user and display the 'You are logged out' message.
    """

    # RemovedInDjango50Warning: when the deprecation ends, remove "get" and
    # "head" from http_method_names.
    http_method_names = ["get", "head", "post", "options"]
    template_name = "registration/logged_out.html"
    extra_context = None

httmp_method_names, template_name 등은 인스턴스 생성 시 as_view()의 인자로 처리해서 재정의할 수 있는 부분이다.

4)

def signup(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid(): 
            signed_user = form.save()
            auth_login(request, signed_user)

auth_login의 두 번째 인자인 user로 signerd_user를 넘겼지만, 이건 인간적인 해석에 가까운 것 같다. 좀 더 기계적인 해석으로는 ModelForm 클래스가 생성한 form 인스턴스가 저장된 것에 불과한 것이 맞는 것 같다.

유효한 form을 내면 signed_user를 생성하고 이게 인자로 적용된 login을 contrib.auth 내 views.py의 login으로 수행한다.

0개의 댓글