herokuでDjangoブログ：ログイン実装

[色々](http://qiita.com/juniskw/items/65129572fa1b3f80d879)ありましたが、ログイン機能を実装したのでその手順を復習していこうと思います。

参考：http://docs.djangoproject.jp/en/latest/topics/auth.html#web

ログイン・ログアウトともに便利なモジュールがあるので比較的簡単に実装できた。

### まずはビュー関数。

###### views.py

```py
from django.contrib.auth import authenticate  # 認証用モジュール
#....
def log_in(req):
	from django.contrib.auth import login  # ログイン用

	user = None  # GET時のNameErrorを防ぐための仮定義

	if req.method=='POST':
		uname = req.POST['username']  # ログイン用のフォームで
		pword = req.POST['password']  # それぞれ送信・受信する
		user = authenticate( username=uname,password=pword )
                # usernameとpasswordでユーザー認証をおこない、結果を変数userに代入

		if user is not None:  # 認証に失敗するとNoneになる
			if user.is_active:  # 存在してもactiveでないユーザーはログイン不可

				login(req,user)  # これだけ。引数を忘れずに

				return HttpResponseRedirect(req.GET['next'])
                                # URL末尾に/?next=/page/を指定し、リダイレクト先を動的にする。

	contexts = RequestContext(req,{
		'request':req.method,
		'user':user,
	})
	template = loader.get_template('blog_in_heroku/login.html')

	return HttpResponse( template.render(contexts) )

def log_out(req):
	from django.contrib.auth import logout  # ログアウト用
	logout(req)  # こちらもHttpRequestオブジェクトが引数に必要みたい
	
	template = loader.get_template('blog_in_heroku/logout.html')
	contexts = Context({})

	return HttpResponse( template.render(contexts) )
```

なお、例に習って今回もショートカットを一切使わずに記述した。認証用のショートカットもあるようなので、本来ならこれよりもはるかに短く書けると思う（詳しくは上記参考ページ）。

### 続いてテンプレートを書く。

###### login.html

```django
<html>
	<head>
		<title>ろぐいん</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
		<script src="https://code.jquery.com/jquery.js"></script>
		<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
	</head>
	<body>
		<div class="jumbotron">
			<div class="container">
				{% ifequal request "POST" %}
					{% if not user.is_authenticated %}
				<div class="alert alert-danger">
					<strong>入力情報が誤っています。</strong>
				</div>
					{% else %}<!-- 動かず -->
						{% if not user.is_active %}
				<div class="alert alert-danger">
					<strong>このユーザーは失効されています。</strong>
				</div>
						{% endif %}
					{% endif %}
				{% else %}
				<div class="alert alert-info">
					<h3><strong>ユーザー名・パスワードを入力してください。</strong></h3>
				</div>
				{% endifequal %}
				<div class="col-xs-6">
					<form class="form-horizontal" role="form" action="" method="post">
					{% csrf_token %}
						<div class="form-group">
							<label for="uname">ユーザー名</label>
							<input type="text" class="form-control input-lg" id="uname" name="username" />
						</div>
						<div class="form-group">
							<label for="pass">パスワード</label>
							<input type="password" class="form-control input-lg" id="pass" name="password" />
						</div>
						<br/>
						<div class="form-group">
							<input class="btn btn-info btn-lg" type="submit" value="ログイン" />
							<a type="button" href="/" class="btn btn-warning btn-lg">キャンセル</a>
						</div>
					</form>
				</div>
				<br/>

			</div>
		</div>
	</body>
</html>
```

エラーメッセージ用のスクリプトのせいで長くなっているが、formタグの内側だけあれば機能としては事足りる。
ちなみに\<!-- 動かず -->としている部分は、 **テスト用にアカウントを作ったアカウントのactiveを解除して試したのだが動かなかった** のでとりあえずコメントしてある。

###### logout.html

```django
<html>
	<head>
		<title>ろぐあうと</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
		<script src="https://code.jquery.com/jquery.js"></script>
		<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
	</head>
	<body>
		<div class="jumbotron">
			<div class="container">
				<div class="page-header">
					<h2>ログアウトしました。</h2>
				</div>
				<a type="button" class="btn btn-success btn-lg" href="/">トップページに戻る</a>
				<a type="button" class="btn btn-info btn-lg" href="/login/?next=/">別のアカウントでログイン</a>
			</div>
		</div>
	</body>
</html>
```

こちらはある種飾りみたいなもの。「別アカウントでログイン」のリンクURLにだけ注意。
**今回のビュー関数の書き方だとちゃんとnextを指定しないとエラーになる。**

現時点での様子：http://my-1st-django-blog.herokuapp.com/