【Django】错误「AttributeError: 模块’django.contrib.admin’没有’display’属性」的原因是什么?

简要概述

当运行之前创建的以下教程时,出现了 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版本是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之后引入的。

已新增了一种新的装饰器display()和action(),供管理员使用。
引用自:Django 3.2 LTS 主要变更摘要

在教程中明确提到了Django的版本是4.1。

本教程是为Django 4.1编写的。

由于我自己尝试使用Django 3.0.5版本启动了polls应用程序,所以上述错误发生了。

@ admin.display 是什么?

@admin.display装饰器是用于定制Django管理站点(Admin Site)中的模型字段和方法的装饰器。您可以将特定字段名称更改为管理员所需的任何名称。

如果要隐藏@admin.display,应按以下方式操作。

image.png

如果存在 @admin.display,则会如下所示。可以看到 ‘最近发布?’ 部分已经发生了变化。

image.png

请查看Django教程中的admin.py和tests.py文件以获取详细的配置信息。

这是解决问题的一种方法。

所以,解决方法有两个。
第一种是在4.1版本后安装Django。

如果您继续使用3.0.5版本的话,
那么您可以使用admin_order_field、boolean和short_description属性来指定自定义的显示方式,而不是使用@admin.display装饰器。

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之前的版本中使用,只需按照上述方式进行更改即可成功。

bannerAds