Webアプリ開発実践：Djangoでシフト作成ページを作ろう！（認証系の処理）

[前回の投稿](http://qiita.com/juniskw/items/0cd00c2bf3160e7d42d1)からだいぶ間が空いてしまいましたが続きをやっていこうと思います。

実は作業自体は結構勝手に進めてしまっていてただ単に投稿をしていなかった感じなので、今回からはそれらを少しずつ小出しにしていくとしましょう。

まずは軽めに、認証系の処理から。[自分がやった過去の投稿](http://qiita.com/juniskw/items/db41f8d25d06c4a35165)を参考にして実装。

###### owner/views.py

```py
from django.shortcuts import render,redirect
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required


def log_in(req):

	if req.user.is_authenticated():
		return redirect('/')  # 認証されていたらトップページ（今回は触れないが）にリダイレクト

	error_msg = ""  # エラーメッセージを定義してテンプレートに持っていく

	if req.method == 'POST':
		posted = req.POST
		name,password = posted['name'],posted['password']

		user = authenticate(username=name,password=password)

		if user is not None:
			if user.is_active:
				login(req,user)

				return redirect('/')
			else:
				error_msg = "This account is not active..."
		else:
			error_msg = "Log in failed...."
				
	return render(req,'owner/log_in.html',{'error_msg':error_msg}) 


def log_out(req):
	logout(req)

	return redirect('/login/')  # ログアウトしたらログイン画面に戻る


def new_owner(req):  # 新しいUserを作るページ。シフトの所有者なのでownerとしている

	error_msg = ""

	if req.method == 'POST':
		posted = req.POST
		name,password = posted['name'],posted['password']

		if password != posted['pass_check']:  # よくあるように２回入力してパスワードをチェック
			error_msg = "Password check is failed!"
		else:
			if len(password) < 6:  # パスワードは６文字以上にしとく
				error_msg = "Password need over 6 letters!"
			else:
				from django.db import IntegrityError
				from django.contrib.auth.models import User
				try:
					owner = User.objects.create_user(username=name,password=password)
					return redirect('/')
				except IntegrityError:  # ユーザー名が既に使われているとこのエラーを吐くので対策
					error_msg = "You can not use this name!"

	return render(req,'owner/new_owner.html',{'error_msg':error_msg,})


@login_required  # 要ログインにするための便利なデコレータ（settingsにLOGIN_URLを設定しておく必要がある。あとはそのURLに自分のログインページを置けばOK）
def edit_groupschedule(req):  # シフトの設定を決める感じなのでshiftsettingとしたほうが分かりやすいかも
	from django.contrib.auth.models import Group
	from owner.models import GroupSchedule
	
	try:  # アクセスしたユーザーがまだGroupScheduleを持っていなかったら新規作成、すでに持っていたら編集という風に動的にしてみた
		groupschedule = GroupSchedule.objects.get(owner=req.user)
		group = groupschedule.group
	except GroupSchedule.DoesNotExist:
		groupschedule = GroupSchedule(owner=req.user)
		group = Group()

	if req.method == 'POST':
		posted = req.POST

		group.name = posted['name']
		group.save()

		groupschedule.group = group
		groupschedule.start_point = int(posted['start_point'])
		groupschedule.save()

		return redirect('/')  # セーブしたらトップへジャンプ

	return render(req,'owner/edit_groupschedule.html',{
		'group_name':group.name,
		'start_point':groupschedule.start_point,
		'select_choices':(1,5,10,15,20,25,),  # 毎月のシフト開始日の候補
	})

```

次はテンプレート。Bootstrapを使用しているのですがフォームの部品を作る度に```<div>```を書いたりするのはちょっと面倒くさいので、繰り返し使いそうな部品はそれぞれの **templates/app** 以下に **parts** というディレクトリを作って置いおきます。あとは **include** というテンプレートタグを使えばそれを引っ張ってくることが出来ます。 **extendsは土台で、includeは部品** というイメージか。

例えばこんな感じ。

###### parts/input.html

```django
<div class="form-group">
	<label>{{ label }}
		<input type="{{ type }}" name="{{ name }}" class="form-control {{ class }}" value="{{ value }}">
	</label>
</div>
```

あとは適当に作っていくといい。それぞれの変数の中には部品を読み込む際に値を入れることが出来るのでクラスを足したりすることも可能。さらに、これをベースにしてアプリケーション用の部品を作製したのでそれを使う。

###### templates/owner/log_in.html

```django
{% extends 'bases/base_form.html' %}

{% block title %}Log in{% endblock %}

{% block form %}
<h1>Log in<small>{{ error_msg }}</small></h1>  <!--エラーがあればメッセージ表示-->
	{% include 'owner/parts/name_input.html' %}
	{% include 'owner/parts/pass_input.html' %}

	{% include 'parts/submit.html' with class='btn-lg btn-primary' value='Log in!' %}  {# withで変数に値を入れることができる #}
	<a href="/owner/new">Create New User</a>
{% endblock form %}
```

あとは大体同じ。

###### ..../new_user.html

```django
{% extends 'owner/bases/base_form.html' %}

{% block title %}new Owner!{% endblock %}

{% block form %}
<h1>new Owner!<small>{{ error_msg }}</small></h1>
	{% include 'owner/parts/name_input.html' %}
	{% include 'owner/parts/pass_input.html' %}
	{% include 'owner/parts/pass_input2.html' %}

	{% include 'parts/submit.html' with value="Create new owner!" %}
{% endblock form %}
```

###### ..../edit_groupschedule.html

```django
{% extends 'owner/bases/base_form.html' %}

{% block title %}new Schedule!{% endblock %}

{% block form %}
	{% include 'owner/parts/name_input.html' with value=group_name %}  {# 初期値。views.pyから持ってきた変数をさらに部品に渡す感じ #}
	{% include 'owner/parts/select_number.html' with start_point=start_point select_choices=select_choices %}  {# 選択候補 #}
	{% include 'owner/parts/submit.html' with value='Create your Schedule!' %}
{% endblock form %}
```

どうでもいいといえばどうでもいいですが、ブランクを空けてみて自分のコードがいかに分かりづらいかを実感しました（クラスとか関数名も意味が通らないものがあるし）。それが恥ずかしいから投稿する気もあまり起こらず、「まあいいや」と思って自分だけで進めていたらますます散らかっていくという悪循環。
とりあえずやったところまでは投稿していこうと思いますが、もういっそゼロから作り直したほうが気持ちよく書いていけそうな気がする。