Webアプリ開発実践：Djangoでシフト作成ページを作ろう！（adminページで実験）

#### 実際のページに手をつける前に、作ったモデルが本当に問題ないかをチェックしたいと思います。

タイトルにある通り、adminページを使用します。
ここで実験してみたいのは、

1. **日付で予定にフィルターをかける**

2. **リレーションを逆に辿る**

です。
いずれも[チュートリアル](http://docs.djangoproject.jp/en/latest/intro/tutorial01.html)であったような気がしたので、復習がてらやってみました。

いじるのはそれぞれのadmin.pyです。
順番に見ていきましょう。

###### schedule/admin.py

```py
from django.contrib import admin
from schedule.models import WorkTime,MonthShift,StaffSchedule,NgShift,GuestSchedule


#### base classes ####

class DateAdmin(admin.ModelAdmin):

	def schedule_date(self,obj):  # objにはモデルオブジェクトが入る
		return obj.strfdate()  # チェンジリストページに表示したい内容を返す

	date_hierarchy = 'date'  # 日付オブジェクトでの絞り込み機能を設定


class TimeTableAdmin(admin.ModelAdmin):

	def time_table(self,obj):
		return obj.strftimetable()


#### main classes ####

###### staff ######
class MonthShiftAdmin(admin.ModelAdmin):
	list_display = ('year','month','groupschedule','completed',)  # チェンジリストページに表示する項目リスト、またはタプル。
	list_filter = ('groupschedule',)  # 指定した項目でのフィルタ機能を付与

admin.site.register(MonthShift,MonthShiftAdmin)  # 第二引数にadmin用のモデルを入れて適用


class WorkTimeAdmin(TimeTableAdmin):
	list_display = ('title','time_table',)	# time_tableは親からの関数
	list_filter = ('groupschedule',)

admin.site.register(WorkTime,WorkTimeAdmin)


class StaffScheduleAdmin(DateAdmin):
	list_display = ('schedule_date','staff','worktime',)	# schedule_dateは親からの関数

	list_filter = ('staff__groupschedule','date','staff',)  # アンダースコア二本で逆リレーションを辿れる

admin.site.register(StaffSchedule,StaffScheduleAdmin)


class NgShiftAdmin(DateAdmin):
	list_display = ('staff','schedule_date','get_values')

	def get_values(self,obj):
		return obj.ng_values()

	list_filter = ['date','staff',]

admin.site.register(NgShift,NgShiftAdmin)


###### guest ######
class GuestScheduleAdmin(DateAdmin,TimeTableAdmin):
	list_display = ('schedule_date','guest','time_table',)

	list_filter = ['date','guest',]

admin.site.register(GuestSchedule,GuestScheduleAdmin)
```

親クラスを定義してコードの記述量を節約しています。
list_filterにより項目の絞り込みを実験。日付ごとに分けて見ることもできたので、シフト表を作るときは似たような感じでやればいいでしょう。

###### staff/admin.py

```py
from django.contrib import admin
from staff.models import Staff


class StaffAdmin(admin.ModelAdmin):
	list_display = ('name','ng_list',)
	list_filter = ('groupschedule',)

	def ng_list(self,obj):
		ngs = ""

		for ng in obj.ngshift_set.all():
			ngs += "%s(%s) ," % ( ng.date,ng.ng_values(), )

		return ngs

admin.site.register(Staff,StaffAdmin)
```

xxxx_setでの逆リレーションも成功。

###### guest/admin.py

```py
from django.contrib import admin
from guest.models import Guest


class GuestAdmin(admin.ModelAdmin):
	list_display = ('name','get_schedules',)
	list_filter = ('groupschedule',)

	def get_schedules(self,obj):
		schedules = ""

		for schedule in obj.guestschedule_set.all():
			schedules += "%s(%s) ," % ( schedule.date,schedule.strftimetable(), )

		return schedules

	get_schedules.short_description = 'Schedules'

admin.site.register(Guest,GuestAdmin)

```

staff/admin.pyとさほど変わらずですね。

###### owner/admin.py

```py
from django.contrib import admin
from owner.models import GroupSchedule


class GroupScheduleAdmin(admin.ModelAdmin):
	list_display = ('group','owner',)


admin.site.register(GroupSchedule,GroupScheduleAdmin)
```

面倒くさくなってきたので特にめぼしい昨日は付けず。最終的に管理者画面は使わないつもりなのでこれでいいでしょう。

## 次回は『スケジュール表のテンプレートを書く』をやるつもりです。