将模型添加到Django Admin
还有一个关键的部分我们还没有完成。 让我们将自己的模型添加到管理站点,所以我们可以使用这个漂亮的界面添加,更改和删除我们的自定义数据库表中的对象。 我们将继续第4章的书籍例子,在这里我们定义了三种模型:发布者,作者和书。 在books目录(mysite_project \ mysite \ books)中,startapp应该创建了一个名为admin.py的文件,如果不是的话,只需要自己创建一个文件,然后输入以下几行代码:
from django.contrib import admin
from .models import Publisher, Author, Book
admin.site.register(Publisher)
admin.site.register(Author)
admin.site.register(Book)
该代码告诉Django管理站点为每个模型提供一个接口。 完成此操作后,请转至您的Web浏览器的管理主页(http://127.0.0.1:8000/admin/),您应该看到“书籍”部分包含作者,书籍和发布者的链接。 您可能必须停止并启动开发服务器才能使更改生效
模型生效后的界面.png现在,您可以为这三种模型中的每一种提供功能齐全的管理界面。 那很简单!
花些时间来添加和更改记录,用一些数据填充数据库。 如果您遵循了第4章创建Publisher对象的示例(并且您没有删除它们),则您将在发布者更改列表页面上看到这些记录。
这里值得一提的一个功能是管理站点处理外键和多对多关系,这两个关系都出现在Book模型中。 提醒一下,以下是Book模型的样子:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __str__(self):
return self.title
在Django管理站点的“添加书籍”页面(http://127.0.0.1:8000/admin/books/book/add/)上,发布者(ForeignKey)由选择框表示,authors字段(a ManyToManyField)由多选框表示。 两个字段都位于绿色加号图标旁边,可让您添加该类型的相关记录。
添加书籍界面.png例如,如果您点击“发布商”字段旁边的绿色加号,则会弹出一个窗口,让您添加发布商。 在弹出窗口中成功创建发布者之后,将使用新创建的发布者更新“添加书籍”表单。
使字段可选
在管理站点玩了一段时间之后,您可能会注意到一个限制 - 编辑表单需要填写每个字段,而在许多情况下,您希望某些字段是可选的。 比方说,我们希望我们的作者模型的电子邮件字段是可选的 - 也就是说,应该允许空白字符串。 在现实世界中,您可能没有每个作者的电子邮件地址。
要指定电子邮件字段是可选的,请编辑Author模型(您将从第4章回忆,它位于mysite / books / models.py中)。 只需将blank= True添加到电子邮件字段,如下所示:
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True)
这告诉Django作者的电子邮件地址确实允许空白值。默认情况下,所有字段都是空白= False,这意味着空白值是不允许的。
这里发生了一些有趣的事情。到目前为止,除__str __()方法之外,我们的模型已经作为我们的数据库表的定义 - 实质上是SQL CREATE TABLE语句的Pythonic表达式。在添加blank = True时,我们已经开始扩展我们的模型,而不是简单地定义数据库表的样子。
现在,我们的模型类已经开始成为关于作者的更丰富的知识集合
对象是,他们可以做什么。不仅是由VARCHAR表示的电子邮件字段
数据库中的列;它也是一个可选的字段,如Django管理站点。
一旦你添加了blank=True,重新加载“添加作者”编辑表单(http://127.0.0.1:8000/admin/books/author/add/),你会注意到该字段的标签 - “电子邮件“ - 不再粗体。这表示它不是必填字段。您现在可以添加作者而无需提供电子邮件地址;如果该字段被提交为空,则不会再获得“该字段是必需的”消息。
使日期和数字字段可选
与blank = True相关的常见问题与日期和数字字段有关,但需要相当数量的背景说明。 SQL有自己的指定空值的方式 - 一个叫NULL的特殊值。 NULL可能意味着“未知”或“无效”或其他应用程序特定的含义。在SQL中,NULL的值与空字符串不同,正如特殊的Python对象None与空Python字符串(“”)不同。
这意味着特定字符字段(例如,VARCHAR列)可能包含NULL值和空字符串值。这可能会导致不必要的模糊和混乱:“为什么这个记录有一个NULL,但这另一个有一个空字符串?有没有区别,还是刚刚输入的数据不一致?“和:”我如何获得所有有空值的记录 - 我应该查找空记录还是空字符串,还是只选择空记录弦?”
为了避免这种歧义,Django自动生成的CREATE TABLE语句(在第4章中介绍)为每个列定义添加一个显式的NOT NULL。例如,下面是我们的作者模型生成的语句,从第4章开始:
CREATE TABLE "books_author" (
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(40) NOT NULL,
"email" varchar(75) NOT NULL
);
在大多数情况下,这种默认行为对于您的应用程序是最佳的,并且可以帮助您避免数据不一致性问题。而且它与Django的其他部分很好地协同工作,例如Django的管理站点,当你留下一个空白的字符字段时,插入一个空字符串(不是NULL值)。
但是,数据库列类型有一个例外,它不接受空字符串作为有效值 - 例如日期,时间和数字。如果您尝试在日期或整数列中插入空字符串,则可能会出现数据库错误,具体取决于您正在使用的数据库。 (严格的PostgreSQL会在这里引发一个异常; MySQL可能会接受它,也可能不会,这取决于您使用的版本,一天中的时间以及月相的相位。
在这种情况下,NULL是指定空值的唯一方法。在Django模型中,通过向字段添加null = True来指定允许使用NULL。所以说这是一个很长的路要走 - 如果你想允许在日期字段(例如,DateField,TimeField,DateTimeField)或数字字段(例如,IntegerField,DecimalField,FloatField)中的空值,您将需要使用null =True,blank=True。
例如,让我们更改我们的Book模型以允许空白的publication_date。这是修改后的代码:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField(blank=True, null=True)
添加null = True比添加blank = True要复杂得多,因为null = True会更改数据库的语义 - 也就是说,它将更改CREATE TABLE语句以从publication_date字段中除去NOT NULL。 为了完成这个改变,我们需要更新数据库。
出于多种原因,Django不会尝试自动化对数据库模式的更改,因此,只要您对模型进行了这样的更改,您就有责任执行python manage.py migrate命令。 回到管理网站,现在“添加书籍”编辑表单应该允许空的发布日期值。
自定义字段标签
在管理网站的编辑表单上,每个字段的标签都是从其模型字段名称生成的。 该算法很简单 - Django只是用空格替换下划线,并将第一个字符大写,因此,例如,Book模型的publication_date字段具有“发布日期”标签。
但是,字段名称并不总是适合于很好的管理员字段标签,所以在某些情况下,您可能需要自定义标签。 您可以通过在相应的模型字段中指定verbose_name来完成此操作。 例如,以下是我们如何使用连字符将Author.email字段的标签更改为“电子邮件”:
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name ='e-mail')
进行更改并重新加载服务器,并且您应该在作者编辑表单上看到该字段的新标签。 请注意,除非总是使用大写字母(例如,“USA state”),否则不应将大写字母的首字母大写。 Django将在需要时自动将其大写,并在其他不需要大写的地方使用确切的verbose_name值。
自定义ModelAdmin类
我们到目前为止所做的更改 - blank = True,null = True和verbose_name - 实际上是模型级别的更改,而不是管理级别的更改。 也就是说,这些变化是模型的一个基本组成部分,正好恰好被管理网站使用; 关于他们并没有什么管理特定。
除此之外,Django管理站点提供了丰富的选项,可让您自定义管理站点对特定模型的工作方式。 这些选项存在于ModelAdmin类中,这些类是包含特定管理站点实例中特定模型的配置的类。