#前回まで
前回はtemplatesの中に綺麗にしましたし、POP-UPメッセージも表示させました。ようやくLoginとLogoutについて書きます!
これは始まる前のFileの構成は前回と変わらないです。これは始まる前のFileの構成は前回と変わらないです。
#流れ
- views.pyで/login のFunctionを作る
- urls.pyでloginのurl pathを入れる
- login.htmlをtemplatesに追加
- navbar.htmlを修正する
- views,pyで/logoutのFunctionを作る
- urls.pyでlogoutのurl pathを入れる
- 自分のlogin formを作ってみる
- Admin Pageをみてみる
##views.pyで/login のFunctionを作る
流れはこんな感じですね。
もらったリクエストはPOSTかどうかをCHECKします。
もしPOSTでなければ、AuthenticationFormを返しします。
もしPOSTならUserからLoginをしようとしてるとわかってます。
formが有効かどうかを判断します。
もし無効なら、エラーメッセージを返しします。
もし有効なら認証を行います。
認証の結果は無効ならエラーメッセージを返しします。
認証の結果が有効ならLoginし、メッセージ返し、HomeにRedirectしますって感じですね。
form=AuthenticationForm(request,request.POST)
class AuthenticationForm
このFormはUserのLogin用のためです。
1個目のArgumentはRequestで、なのでrequestをそのままに渡しします。
1個目Formの内容です。
user=authenticate(username=username,password=password)
authenticate(request=None, **credentials)
このメソッドを使って認証を行います、認証されるデータセットのはcredentialsに渡しします。
CredentialsはのKeyword Argumentsは2つがあり、Usernameとpasswordです。もう認証okならUser Objectが返してくれます。
if user is not None:
#
なので、認証終わったらあとNoneかどうかを比較するのはその原因です。もしNoneじゃなければ→User Objectがあります→認証OKってことです。
このメソッドを使えばUser Logiすることができます。必要な引数はrequest, userです。
login()を使うことよってDjango SessionでUserIDを保存します。
全体的はこんな感じですね~
def login_request(request):
if request.method=="POST":
form=AuthenticationForm(request,request.POST)
if form.is_valid():
username=form.cleaned_data.get('username')
password=form.cleaned_data.get('password')
user=authenticate(username=username
,password=password
)
if user is not None:
messages.info(request,'Welcome Back,{}.'.format(username))
login(request,user)
return redirect('helloworld:homepage')
else:
messages.error(request,'some error{}.'.format(form.error_messages))
else:
messages.error(request,'some error{}.'.format(form.error_messages))
form=AuthenticationForm()
return render(request
,"helloworld/login.html"
,{"form":form}
)
urls.pyでloginのurl pathを入れる
ここはもう説明しなくてもわかりると思いますー
from django.contrib import admin
from django.urls import path
from . import views
app_name="helloworld"
urlpatterns = [
path('',views.homepage,name='homepage')
,path('register/',views.register,name='register')
,path('login/',views.login_request,name='login')
]
login.htmlをtemplatesに追加
コードは以下です:
{% extends "helloworld/header.html" %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
if you do not had a account,please <strong><a href="/login"></a>Register</strong>.
{% endblock%}}
navbar.htmlを修正する
Loginもし成功したらNav barがまだLoginが表示されるのはおかしいですよね~ここでもしLoginがOKならUser名を表示するようにします。
もしLoginしたら Home Username Logout
もしLoginしてないなら Home Register Login
<nav>
<div class="w3-bar w3-border w3-light-grey">
<a href="/" class="w3-bar-item w3-button w3-mobile">Home</a>
{% if user.is_authenticated %}
<a href="/account" class="w3-bar-item w3-button w3-mobile">{{user.username}}</a>
<a href="/logout" class="w3-bar-item w3-button w3-mobile">logout</a>
{% else %}
<a href="/register" class="w3-bar-item w3-button w3-mobile">Register</a>
<a href="/login" class="w3-bar-item w3-button w3-mobile">Login</a>
{% endif%}
</div>
</nav>
Loginしたら…OKですね!Redirectしましたし、Usernameもちゃんと表示されましたね。
views.pyで/logoutのFunctionを作る
ここで使われてるのはlogout()です。
流れはこんな感じです:
logoutします。
Message表示します。
Homeに戻ります。
def logout_request(request):
logout(request)
messages.info(request,"Logged out,please come back again.")
return redirect('helloworld:homepage')
logout(request)
Log InされたUserをLog outさせます。引数はHttpRequestだけ、戻り値がありません。
urls.pyでlogoutのurl pathを入れる
ここはもう説明しなくてもわかりると思いますー
from django.contrib import admin
from django.urls import path
from . import views
app_name="helloworld"
urlpatterns = [
path('',views.homepage,name='homepage')
,path('register/',views.register,name='register')
,path('login/',views.login_request,name='login')
,path('logout/',views.logout_request,name='logout')
]
自分のlogin formを作ってみる
では自分のloginformも作ってみよう!まずforms.pyを追加しますー。
その中にメールアドレスも必ず入力しないとだめようにします。
File構成はこうになりましたね!
流れとしては...
新しいFrom Classを作ります。
EmailFieldを入力必要項目として作ります。
Meta Classを作ります。
Fieldsはどんな項目いるのかを設定します。
saveメソッドを作ります。
save()が呼びされたときまず一旦Commitをやめます。
user.emailにFormの中に入力されたものを入れます。
Commitします。
次はsaveされた実際どんなものが走ってるの?
- pre-save signalをだします。そのsignalが送ったあと、全てこのsignalを待ってるFunctionも生かしなにかの動作します。
- Preprocess the data。Fields のpre_save()がCallされ、自動的にデータを処理します。
- databaseに送るデータを準備する。Fields のget_db_prep_save()メソッドがデータの現在値をDatabaseに書き込めるのデータタイプに変更する。
- 普通のFieldsが大体そういうデータの準備がいらないです。例えば整数、文字列などもう既にDatabaseに書き込むの“準備“ができました。ですが、普通なデータタイプならそういう先処理が必要です。例えばDateFieldはPythonのdatetime objectsを使ってデータを保存する。DatebaseはPythonのdatetime objectsを保存することができないのでISO-compliant date stringに変換する作業が必要になります。
- 次はデータをDatabaseに挿入します。
- 最後はpost-save signalを出します。すべてのこのsignalを待ってるFunctionを生かしなにかの動作します。
その中のメソッドとかも深すぎるのでここでもう説明しません…私みてもてもわかりません。
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class newUserFrom(UserCreationForm):
email=forms.EmailField(required=True)
class Meta:
model=User
fields=('username','email','password1','password2')
def save(self,commit=False):
user=super(newUserFrom,self).save(commit=False)
user.email=self.clean_data['email']
if commit:
user.save()
return user
Email Fieldsが増えましたね!