在这篇博客中,我将继续利用Django开发Web应用程序:
1.2.3 用Django管理网站:
为应用程序定义模型时,Django提供的管理网站(admin site)让你能够轻松地处理模型。网站的管理员可使用管理网站,但普通用户不能使用。在本节中,我们将建立管理网站, 并通过它使用模型Topic
来添加一些主题。
Django允许你创建具备所有权限的用户——超级用户。权限决定了用户可执行的操作。最严格的权限设置只允许用户阅读网站的公开信息;注册了的用户通常可阅读自己的私有数据,还可查看一些只有会员才能查看的信息。为有效地管理Web应用程序,网站所有者通常需要访问网站存储的所有信息。优秀的管理员会小心对待用户的敏感信息,因为用户对其访问的应用程序有极大的信任。 为在Django中创建超级用户,请执行下面的命令并按提示做:
python manage.py createsuperuser
Django自动在管理网站中添加了一些模型,如User
和Group
,但对于我们创建的模型,必须手工进行注册。 我们创建应用程序learning_logs 时,Django在models.py所在的目录中创建了一个名为admin.py的文件:
为向管理网站注册Topic
,要输入下面的代码:
from django.contrib import admin
from learning_logs.models import Topic
admin.site.register(Topic)
这些代码导入我们要注册的模型Topic
(见第3行),再使用admin.site.register()
(见第5行)让Django通过管理网站管理我们的模型。 现在,使用超级用户账户访问管理网站:访问http://localhost:8000/admin/
,并输入你刚创建的超级用户的用户名和密码,你将看到类似于下图所示的屏幕。这个网页让你能够添加和修改用户和用户组,还可以管理与刚才定义的模型Topic
相关的数据:
向管理网站注册Topic
后,我们来添加第一个主题。为此,单击Topics进入主题网页,它几乎是空的,这是因为我们还没有添加任何主题。单击Add,将看到一个用于添加新主题的表单。在第一个方框中输入Chess ,再单击Save,这将返回到主题管理页面,其中包含刚创建的主题。 下面再创建一个主题,以便有更多的数据可供使用。再次单击Add,并创建另一个主题Rock Climbing 。当单击Save时,将重新回到主题管理页面,其中包含主题Chess和 Rock Climbing,如下图所示:
1.2.4 定义模型Entry:
要记录学到的国际象棋和攀岩知识,需要为用户可在学习笔记中添加的条目定义模型。每个条目都与特定主题相关联,这种关系被称为多对一关系,即多个条目可关联到同一个主题。 下面是模型Entry
的代码:
from django.db import models
class Topic(models.Model):
'''the user learning topic'''
text = models.CharField(max_length = 200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
'''Returns a string representation of the model'''
return self.text
class Entry(models.Model):
'''Specific knowledge learned about a subject'''
topic = models.ForeignKey(Topic)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
'''Returns a string representation of the model'''
return self.text[:50] + '....'
像Topic
一样,Entry
也继承了Django基类Model
(见第12行)。第一个属性topic
是一个ForeignKey
实例(见第14行)。外键是一个数据库术语,它引用了数据库中的另一条记 录;这些代码将每个条目关联到特定的主题。每个主题创建时,都给它分配了一个键(或ID)。需要在两项数据之间建立联系时,Django使用与每项信息相关联的键。稍后我们将根据这些联系获取与特定主题相关联的所有条目。 接下来是属性text
,它是一个TextField
实例(见第15行)。这种字段不需要长度限制,因为我们不想限制条目的长度。属性date_added
让我们能够按创建顺序呈现条目,并在每个条目旁边放置时间戳。 在第18行处,我们在Entry
类中嵌套了Meta
类。Meta
存储用于管理模型的额外信息,在这里,它让我们能够设置一个特殊属性,让Django在需要时使用Entries
来表示多个条目。如果没有这个类, Django将使用Entrys
来表示多个条目。最后,方法__str__()
告诉Django,呈现条目时应显示哪些信息。由于条目包含的文本可能很长,我们让Django只显示text
的前50个字符(见第24行)。我们还添加了一个省略号,指出显示的并非整个条目。由于我们添加了一个新模型,因此需要再次迁移数据库。
然而,我在迁移时却出现了如下问题:
上网搜索后,我找到了原因:在django2.0后,定义外键和一对一关系的时候需要加on_delete
选项,此参数为了避免两个表里的数据不一致问题,不然会报错:
TypeError: __init__() missing 1 required positional argument: 'on_delete'
于是需要将上述代码的第14行改成:
topic = models.ForeignKey(Topic , on_delete=models.CASCADE)
接着执行命令 ,发现Django应用了这种迁移且一切顺利:
1.2.5 向管理网站注册Entry:
我们还需要注册模型Entry
。为此,需要将admin.py修改成类似于下面这样:
from django.contrib import admin
from learning_logs.models import Topic, Entry
admin.site.register(Topic)
admin.site.register(Entry)
返回到http://localhost/admin/
,将看到learning_logs下列出了Entries。单击Entries的Add链接,或者单击Entries再选择Add entry。将看到一个下拉列表,能够选择要为哪个主题创建条目,还有一个用于输入条目的文本框:
( 如果在浏览器中看到一条消息,指出访问的网页不可用,请确认在终端窗口中运行着Django服务器。如果没有,请激活虚拟环境,并执行命令python manage.py runserver
)
当单击Save时,将返回到主条目管理页面。在这里,将发现使用text[:50]
作为条目的字符串表示的好处:管理界面中,只显示了条目的开头部分而不是其所有文本,这使得管理多个条目容易得多: