Python 学习笔记

将模型添加到Django Admin

2018-02-01  本文已影响88人  大爷的二舅

还有一个关键的部分我们还没有完成。 让我们将自己的模型添加到管理站点,所以我们可以使用这个漂亮的界面添加,更改和删除我们的自定义数据库表中的对象。 我们将继续第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类中,这些类是包含特定管理站点实例中特定模型的配置的类。

上一篇下一篇

猜你喜欢

热点阅读