概要
以前作成した以下チュートリアルを動かしていたら、AttributeError: module 'django.contrib.admin' has no attribute 'display'
というエラーが出ました。
はじめての Django アプリ作成、その 1
本記事では、このエラーの解決方法を記載します。
エラー内容
Traceback (most recent call last):
# 中略
File "/mysite/mysite/polls/models.py", line 7, in <module>
class Question(models.Model):
File "/mysite/mysite/polls/models.py", line 12, in Question
@admin.display(boolean=True, ordering='pub_date', description='Published recently?')
AttributeError: module 'django.contrib.admin' has no attribute 'display'
使用しているdjangoのバージョンはDjango 3.0.5です。
エラー原因
まず、エラーになったコードは以下models.py
です。
import datetime
from django.db import models
from django.utils import timezone
from django.contrib import admin
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
@admin.display(
boolean=True,
ordering='pub_date',
description='Published recently?',
)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
なぜ上記コードでエラーになったのか?
それは、Django 3.0.5では@admin.display
デコレータは使用できないため。
@admin.display
デコレータはDjango 3.2以降で導入されたらしい。
admin用の新しいデコレータdisplay()・action()が追加されました。
引用元:Django 3.2 LTS 主な変更点まとめ
確かに、チュートリアルでのDjangoのバージョンは、以下のように、4.1
と記載があります。
This tutorial is written for Django 4.1,
今回、自分がDjangoのバージョンを3.0.5でpolls
アプリを立ち上げようとしたため、上述のエラーが発生したのです。
@admin.display
とは?
@admin.display
デコレータとは、Djangoの管理サイト(Admin Site)でモデルのフィールドやメソッドをカスタマイズするために使用されるデコレータです。特定のフィールド名を管理者用に任意の名前に変更したりできます。
@admin.display
を消す場合、以下のようになります。
@admin.display
がある場合、以下のようになります。
'Published recently?'
の部分(任意に決めた部分)が変わっていることが分かります。
djangoチュートリアルでは、admin.py
とtests.py
で詳細な設定をしているので、気になる方はそちらをご参照ください。
解決策
ということで、解決方法は二つ。
一つ目は、Djangoを4.1
以降でインストールする。
二つ目は、3.0.5を使い続ける場合。
その場合は、@admin.display
デコレータの代わりにadmin_order_field、boolean
、short_description
属性を使用してカスタムの表示方法を指定します。
from django.db import models
from django.utils import timezone
from django.contrib import admin
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 - timezone.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?'
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
ということで、原因はDjangoチュートリアルで推奨のバージョンを使用していなかった、ということでした。もしも3.2より前で使ってみたい場合は上記のように変えるとうまくいきます。