3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

django#008_loginとlogout

Posted at

#前回まで
前回はtemplatesの中に綺麗にしましたし、POP-UPメッセージも表示させました。ようやくLoginとLogoutについて書きます!
これは始まる前のFileの構成は前回と変わらないです。これは始まる前のFileの構成は前回と変わらないです。
image.png
#流れ

  • 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に追加

Fileの構成はこうになります。
image.png

コードは以下です:

{% 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もちゃんと表示されましたね。
image.png

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')
]

Logoutしてみたら…OKですね!
image.png

自分のlogin formを作ってみる

では自分のloginformも作ってみよう!まずforms.pyを追加しますー。
その中にメールアドレスも必ず入力しないとだめようにします。
File構成はこうになりましたね!
image.png

流れとしては...
新しいFrom Classを作ります。
EmailFieldを入力必要項目として作ります。
Meta Classを作ります。
Fieldsはどんな項目いるのかを設定します。
saveメソッドを作ります。
save()が呼びされたときまず一旦Commitをやめます。
user.emailにFormの中に入力されたものを入れます。
Commitします。

次はsaveされた実際どんなものが走ってるの?

  1. pre-save signalをだします。そのsignalが送ったあと、全てこのsignalを待ってるFunctionも生かしなにかの動作します。
  2. Preprocess the data。Fields のpre_save()がCallされ、自動的にデータを処理します。
  3. databaseに送るデータを準備する。Fields のget_db_prep_save()メソッドがデータの現在値をDatabaseに書き込めるのデータタイプに変更する。
  4. 普通のFieldsが大体そういうデータの準備がいらないです。例えば整数、文字列などもう既にDatabaseに書き込むの“準備“ができました。ですが、普通なデータタイプならそういう先処理が必要です。例えばDateFieldはPythonのdatetime objectsを使ってデータを保存する。DatebaseはPythonのdatetime objectsを保存することができないのでISO-compliant date stringに変換する作業が必要になります。
  5. 次はデータをDatabaseに挿入します。
  6. 最後は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が増えましたね!

image.png
Admin PageでCheckしてみたら、ちゃんとメールアドレスがついてますね!
image.png

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?