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으로 수행한다.