くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Django Admin Siteが便利すぎてつらい

admin-site便利。

以下、公式サイトより。

Djangoのパワフルな特徴の1つは、自動的に生成されるadminインタフェースです。あなたのモデルクラスからメタデータを読み取り、モデル中心のインタフェースを提供します。このインタフェースのおかげで、ユーザはあなたのサイトのコンテンツを操作することができます。adminサイトのオススメの使い方は、組織内で利用する管理ツールに利用を制限することです。adminサイトは、あなたのサイトのフロントエンドやその周辺を含んだ全体を作成することを意図していません。

  • Modelを作って、
  • Admin Siteに登録すると、
  • Modelの参照・更新・削除の画面を自動生成してくれる 管理画面用のサイト。これがデフォルトの機能なのがすごい。。

urls.py

python manage.py startprojectの雛形で以下のような感じになっている

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

admin.py

python manage.py startappの雛形でadmin.pyがあるので、そこにいろいろ設定 ちなみに、models.pyはこんな感じ。

# models.py
from django.db import models
from django.utils.translation import ugettext_lazy

class Todo(models.Model):
  title = models.CharField('タイトル', max_length=20)
  done = models.BooleanField('完了', default=False)
  
  def __str__(self):
    return "{}".format(self.title)

  class Meta: # 表示クラス名を変更する
    verbose_name = ugettext_lazy("TODO")
    verbose_name_plural = ugettext_lazy("TODO")

admin.ModelAdminを継承したクラスを作って、もろもろを設定

# admin.py
from django.contrib import admin
from .models import Todo

@admin.register(Todo)
class TodoAdmin(admin.ModelAdmin):
  ordering = ['id'] # idの昇順でソート
  list_display = ('id', 'name') # リストで表示するフィールド

小ネタ

ManyToManyFieldを連結した表示にしたい

# models.py
from django.db import models
from django.utils.translation import ugettext_lazy

class Category(models.Model):
  name = models.CharField('カテゴリ名', max_length=20)

class Todo(models.Model):
  title = models.CharField('タイトル', max_length=20)
  done = models.BooleanField('完了', default=False)
  categories = models.ManyToManyField(Category, verbose_name='カテゴリ')
# admin.py
from django.contrib import admin
from .models import Todo

@admin.register(Todo)
class TodoAdmin(admin.ModelAdmin):
  ordering = ['id'] # idの昇順でソート
  list_display = ('id', 'name', 'category_list') # リストで表示するフィールド
  
  # list_displayの独自カラムは関数に置き換えれるので、よい感じの表示に変更
  def category_list(self, obj):
      return ", ".join([cat.name for cat in obj.categories.all()])

ImageFieldを画像で表示したい

# models.py
from django.db import models

class Todo(models.Model):
  title = models.CharField('タイトル', max_length=20)
  done = models.BooleanField('完了', default=False)
  image = models.ImageField()
# admin.py
from django.contrib import admin
from django.utils.html import format_html
from .models import Todo

@admin.register(Todo)
class TodoAdmin(admin.ModelAdmin):
  ordering = ['id'] # idの昇順でソート
  list_display = ('id', 'name', 'thumbnail') # リストで表示するフィールド
  
  # list_displayの独自カラムは関数に置き換えれるので、よい感じの表示に変更
  def thumbnail(self, obj):
      if obj.image and hasattr(obj.image, 'url'):
          return format_html('<img src="{}" width="50" height="50" />', obj.image.url)
      else:
          return 'No Image'

Apacheでデプロイする

設定せずにデプロイすると、adminサイトのcssが読み込まれない。。

1. settings.pyに以下を追加。
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static") # プロジェクトルート直下のstaticディレクトリ
2. 利用されているcssをプロジェクトルート直下のstaticディレクトリに配置
$ python manage.py collectstatic
3. /etc/httpd/con.d/の設定にプロジェクトルート直下のstaticディレクトリを参照するようAlias
Alias /static/ /var/www/my_project/my_app/static/
<Directory /var/www/my_project/my_app/static>
    Require all granted
</Directory>

以上!!

参考にしたサイト様