DreamerDreamのブログ

夢想家の夢です。〜揚げたてのモヤっとしたものをラフレシアと共に〜

Django奮闘記⑩ラストスパートーユーザービリティーー

今回は始めてのDangoアプリ生成の最終章です。

気合いが入ります!

はじめての Django アプリ作成、その 7 | Django documentation | Django

 

前回は画像とスタイルシートを扱いました。

dreamerdream.hateblo.jp

 

今回は使い易さを求めてデフォルトからカスタムするチュートリアルのようです。

adminフォームをデフォルトから変更する方法ですね。 

raspberrypi:~/draemon $ nano polls/admin.py

を編集します。

from django.contrib import admin

# Register your models here.
from .models import Question

class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

 

 

そうすると、日付と質問が入れ替わると。

f:id:DreamerDream:20180905164728p:plain

なりましたね。

モデルの admin のオプションを変更したいときには、モデルごとに admin クラスを作成して、admin.site.register() の 2 番目の引数に渡すと いうパターン

なるほど!

 

class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]

こうすることで分割表示も可能になるんですね!へー!

f:id:DreamerDream:20180905165134p:plain

ユーザービリティを考えて任意に変更出来るのは素晴らしいですね。

 

次の課題、

しかし Question は複数の Choice を持つのに、管理ページには表示されていませんね。

そう!ここ、「Django奮闘記⑥」でかなり悩まされたところなんですよ!最初にこれを教えてほしかったっス。

raspberrypi:~/draemon nano polls/admin.py

の編集だけでChoiceモデルを管理できるそうです!まじすか?

from django.contrib import admin

# Register your models here.
from .models import Question, Choice

class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]

admin.site.register(Question, QuestionAdmin)

admin.site.register(Choice)

 

 

ん?ないぞ?と思ったら、QuestionとChoiceの管理が別になるんですね!なるほど! 

f:id:DreamerDream:20180905165919p:plain

でー、Choiceの入力時にQuestionを選ぶという

f:id:DreamerDream:20180905165930p:plain

確かに選択肢に入っています。

f:id:DreamerDream:20180905165939p:plain

出来ましたが使いにくいですね。

 

使い易いように改造します。

raspberrypi:~/draemon $ nano polls/admin.py

を説明通りに変更、比べるために前回のはコメントアウト

from django.contrib import admin

# Register your models here.
from .models import Question, Choice

class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3

class QuestionAdmin(admin.ModelAdmin):
'''
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
'''
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]

admin.site.register(Question, QuestionAdmin)

 

 

f:id:DreamerDream:20180906084525p:plain

 

class ChoiceInline(admin.StackedInline):

class ChoiceInline(admin.TabularInline):

に変更

f:id:DreamerDream:20180906084940p:plain

なるほど。サンプル通りになりますね

 

それに、list_displayの項目を追加するだけで日付等でリストがソート出来るようになるそうです。

class QuestionAdmin(admin.ModelAdmin):
'''
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
'''
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
list_display = ('question_text', 'pub_date', 'was_published_recently')

 

f:id:DreamerDream:20180906085407p:plain

ほんとだー!便利!

次に

raspberrypi:~/draemon $ nano polls/models.py

に追記すると無効なソートが禁止になる??(よくわからん)。

class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'

 

加えてlist_filter = ['pub_date']を追記するとフィルターが出来る。

raspberrypi:~/draemon $ nano polls/admin.py

に 

inlines = [ChoiceInline]
list_display = ('question_text', 'pub_date', 'was_published_recently')
list_filter = ['pub_date']

 

f:id:DreamerDream:20180906090148p:plain

おおすごい!こんな簡単にフィルターが機能するのに感動です。

 

search_fields = ['question_text']

を追記します。

f:id:DreamerDream:20180906090404p:plain

すっげ!!これは便利だー!!

当たり前ですがちゃんと機能しました。

この管理ページはデフォルトでページ区切りされていて、デフォルトで100件づつ表示されるそうです。さすが!

 

 

次に管理ページ等、デフォルトで指定されているテンプレートの変更の仕方です。

raspberrypi:~/draemon $ nano draemon/settings.py

こちらのテンプレートDIRS設定を書き換えます。

'DIRS': [os.path.join(BASE_DIR, 'templates')],

ディレクトリtemplatesを作ってさらにadminディレクトリを作るそうです。

たぶん、settingファイルを弄ったプロジェクトファイルだろうと踏んでプロジェクトファイルに作ってみます。

raspberrypi:~/draemon $ mkdir draemon/templates
raspberrypi:~/draemon $ mkdir draemon/templates/admin

Djangoのソースファイルの場所を探します。

raspberrypi:~/draemon $ python3 -c "import django; print(django.__path__)"
['/usr/local/lib/python3.5/dist-packages/django']

指定されたbase_site.htmlをコピーします。

raspberrypi:~/draemon $ cp /usr/local/lib/python3.5/dist-packages/django/contrib/admin/templates/admin/base_site.html draemon/templates/admin/

 

raspberrypi:~/draemon $ nano draemon/templates/admin/base_site.html

を書き換えるんですね。

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

で、表示すると、、、

f:id:DreamerDream:20180906092443p:plain

おや?全く変わっていません。

もう一度読み返すと、

templates ディレクトリをプロジェクトディレクトリ (manage.py が置かれているディレクトリ) に作成してください。

と書かれていました。あらら、ディレクトリを移動します。

raspberrypi:~/draemon $ mv draemon/templates templates

f:id:DreamerDream:20180906094951p:plain

おお!タイトルがPollsAdministrationに変わっています。今度は成功です。

 

要はどこのページでもこのデフォルトのテンプレートをコピーすることで任意に編集が出来るってことですね。試しに

raspberrypi:~/draemon $ cp /usr/local/lib/python3.5/dist-packages/django/contrib/admin/templates/admin/index.html templates/admin/

index.htmlを自分のtemplate/adminにコピーしてテキトーにtestと書いて保存

{% block content %}
<div id="content-main">

test
{% if app_list %}
{% for app in app_list %}

 

ホントだ、反映されてる。

f:id:DreamerDream:20180906100458p:plain

これは簡単!

 

さて、10回にも渡るDjango奮闘記でしたが、ひとまずこれで参考サイト「初めてのDjangoアプリ作成」チュートリアルを終えました。

とりあえずDjangoを使えばセキュアな管理ページが作れたりカスタムで来たりと便利な機能が簡単に扱えるということは解りました。不明な点もまだあるものの、一通りRaspberryPiで実際に試してみました。

初心者の遭遇した全てのエラー、凡ミスをすべて記録したものですので「これからDjangoを初めてみようかな?」と考えている方への参考になりましたら幸いです。

 

これからもDreamerDreamのブログをどうぞよろしくお願いいたします。

 

 徐々に纏めていきます。↓

dreamerdream.hateblo.jp

 

kampa.me