3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Django+Reactで学ぶプログラミング基礎(15): Djangoチュートリアル(投票アプリその7-1)

Last updated at Posted at 2022-06-10
[前回] Django+Reactで学ぶプログラミング基礎(14): Djangoチュートリアル(投票アプリその6)

はじめに

Django公式チュートリアル、その7-1です。
前回は、Djangoの静的ファイルをカスタマイズしました。
今回は、管理サイトをカスタマイズします。

Djangoアプリ作成(その7-1): 投票(poll)アプリ

今回の内容

  • 管理フォームをカスタマイズ
  • リレーションを張ったオブジェクトを追加

管理フォームのカスタマイズ

  • デフォルトで、モデル登録フォームの作成方法
    • admin.site.register(モデル名)を呼び出す
      • すると、Djangoがデフォルト形式でオブジェクトを表示してくれる
  • 管理フォームの表示や操作をカスタマイズしたい
    • オブジェクト登録時に、オプションを指定
      • モデルごとにadminクラスを作成し、admin.site.register()の2番目の引数に渡す

質問登録フォームでフィールドの並び順を変えてみる

  • Publication dateフィールドの表示位置をQuestionフィールドより前に変更
polls/admin.py
from random import choices
from django.contrib import admin

from .models import Question,Choice

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

admin.site.register(Question, QuestionAdmin)

admin.site.register(Choice)

image.png

  • VS Codeからサーバーを起動(すでに起動済みの場合は再起動)
C:\kanban\pollsite>..\venv\.venv\Scripts\activate
(venv) C:\kanban\pollsite>python manage.py runserver
  • ブラウザで、管理サイトの質問登録画面にアクセス
    • http://127.0.0.1:8000/admin/polls/question/add/
      image.png

フォームを複数のフィールドセットに分割してみる

  • fieldsetsの各タプルの先頭の要素が、フィールドセットのタイトル
polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        ('質問文',   {'fields': ['question_text']}),
        ('日付情報', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

image.png

リレーションを張ったオブジェクトを追加

質問の管理ページに、関連する選択肢を表示したい

方法1: 質問と同じ方法で、管理サイトにChoiceを登録(実装済)
polls/admin.py
from random import choices
from django.contrib import admin

from .models import Question,Choice

from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        ('質問文',   {'fields': ['question_text']}),
        ('日付情報', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

admin.site.register(Choice)

image.png

  • ブラウザで、管理サイトの選択肢登録画面にアクセス

    • http://127.0.0.1:8000/admin/polls/choice/add/
      image.png
  • 選択肢登録フォームで、Questionフィールドは選択ボックスとなる

    • データベース上の全ての質問を選択可能
    • Djangoは外部キー(ForeignKey)表示に、<select>ボックスを使ってくれる
  • Questionフィールドの隣にある+(質問を追加)リンクをクリック

    • ForeignKeyオブジェクトに対し、デフォルトでこのリンクが表示される
    • 質問を追加ポップアップウィンドウが表示される
      • 質問を追加し、保存を押すと、質問がデータベースに保存される
      • 元の、選択肢追加フォームに選択済み項目として動的に追加される
        image.png
方法2: 質問追加時、選択肢も合わせて追加
  • 方法1の問題
    • Choiceオブジェクトのシステムへの追加が非効率
    • 解決案
      • Questionオブジェクト追加時に、Choiceをひと揃い追加する
  • Choiceモデルに対するregister()を削除し、
    • Question登録部分を書き換え、以下のように指示
      • ChoiceオブジェクトはQuestion管理ページから編集
      • デフォルトで、 3つのChoiceフィールドを用意
polls/admin.py
from django.contrib import admin

from .models import Choice, Question


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

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

admin.site.register(Question, QuestionAdmin)
  • ブラウザで、質問登録ページを更新(F5)

    • http://127.0.0.1:8000/admin/polls/question/add/
    • Questionと関連付けられたChoice登録用に、3つのスロットが存在(extraに指定した数)
      image.png
  • リレーション先のオブジェクトをコンパクトなテーブル形式で表示

    • ChoiceInline宣言を変更
      • StackedInlineTabularInlineに書き換える
polls/admin.py
class ChoiceInline(admin.TabularInline):
    #...

image.png

おわりに

管理サイトをカスタマイズしました。
次回も続きます。お楽しみに。

[次回] Django+Reactで学ぶプログラミング基礎(16): Djangoチュートリアル(投票アプリその7-2)
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?