newforms-admin初級編 ForeignKey関連

さらに続きです。


ここからがnewforms-adminの肝になってくるのではないでしょうか。


Addressモデルの内容を見てください。
少し足りなくないですか?
住所録としては電話番号がありません。
ということで、モデルを追加します。

class PhoneType(models.Model):
	description = models.CharField(max_length=20)

	def __unicode__(self):
		return self.description

class Phone(models.Model):
	description = models.CharField(max_length=80)
	number = models.PhoneNumberField()
	number_type = models.ForeignKey(PhoneType)
	address = models.ForeignKey(Address)

	def __unicode__(self):
		return self.number

そして次に

manage.py syncdb

を実行してください。


次に、Admin Interfaceで使えるようにします。
ここで入力のことを考えると、電話番号を一つずつ入力するより
表形式で入力するほうが便利です。
それを実現するのが、'admin.TabularInline'です。
'AddressOptions'より前に

class PhoneInline(admin.TabularInline):
	model = Phone
	extra = 3

を追加してください。
この状態でアクセスしてもどこにも表示されません。
Addressモデルのところに表示させたいので、
'AddressOptions'に'inlines'というオプションを追加させる必要があります。

class AddressOptions(admin.ModelAdmin):
	search_fields = ['short_name', 'long_name']
	fieldsets = (
		('Name', {'fields': ('short_name', 'long_name')}),
		('Address', {'fields': ('addr_line_1', 'addr_line_2', 'city', 'state', 'zip')}),
	)
	list_display = ('short_name', 'city', 'state')
	ordering = ('short_name',)
	list_filter = ('state',)
	inlines = [PhoneInline]

これで、各データにアクセスしてみてください。
Addressの下にPhonesという項目が表示され、3つほど入力できるようになりましたが、
なに足りなくありませんか?
そうです、PhoneTypeモデルを作成したのに入力することが出来ません。
models.pyの最終行に以下を追加すれば、各データフォームからも入力することが出来ます。

admin.site.register(PhoneType)

複数のinlineを表示させるには、

class Date(models.Model):
	description = models.CharField(max_length=80)
	start_date = models.DateField()
	annual_event = models.BooleanField()
	address = models.ForeignKey(Address)

のモデルクラスと

class DateInline(admin.TabularInline):
	model = Date
	extra = 2

のクラス、そして以下のように'AddressOptions'を変更します。

class AddressOptions(admin.ModelAdmin):
	search_fields = ['short_name', 'long_name']
	fieldsets = (
		('Name', {'fields': ('short_name', 'long_name')}),
		('Address', {'fields': ('addr_line_1', 'addr_line_2', 'city', 'state', 'zip')}),
	)
	list_display = ('short_name', 'city', 'state')
	ordering = ('short_name',)
	list_filter = ('state',)
	inlines = [PhoneInline, DateInline]

'TabularInline'の他に'StackedInline'もあるので試してみてください。


次はManyToManyを進めていきます。
次で最後かな?