【Django 笔记】Django快速入门 第2节: 模型与后台
笔记基于官方文档和技术博客,从中提取关键信息,和记录笔记,例程详见官方文档。
完整官方文档:Django documentation
博客推荐:Django2.2教程
Django快速入门官方文档:Part 2: Models and the admin site
本部分将建立数据库,创建您的第一个模型,并主要关注 Django 提供的自动生成的管理页面。
目录
1. 模型
模型是Django项目的核心,也是动态网站与数据库交互的核心。
1.1. ORM框架介绍
通常操作数据库是通过写sql语句,但通过ORM框架不写sql语句就可以操作数据库。
- O即Object类对象;
- R即relation关系,也就是关系数据库中数据表的意思;
- M即mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。
ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。
django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作(在models.py设计和表对应的模型类)。
使用django进行数据库开发的步骤:
- 1.在models.py中定义模型类
- 2.迁移
- 3.通过类和对象完成数据增删改查操作
1.2. 数据库配置
如果不是使用默认的SQLite数据库,需要先进行数据库配置,避免以后数据库迁移的相关问题。打开 mysite/settings.py
。这是个包含了 Django 项目设置的 Python 模块。Django默认使用SQLite数据库,如实际的项目中,一般使用其他数据库,如PostgreSQL数据库。
在mysite/settings.py
原来的相关代码段如下:
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
使用其他的数据库时,要:
-
先安装相应的数据库操作模块;
-
并将settings文件中DATABASES位置的
’default’
的键值进行相应的修改,用于连接你的数据库。
一些键值:
- ENGINE(引擎):可以是
django.db.backends.sqlite3
、django.db.backends.postgresql
、django.db.backends.mysql
、django.db.backends.oracle
等
。 - NAME(名称):类似Mysql数据库管理系统中用于保存项目内容的数据库的名字。如果使用的是 SQLite,数据库将是你电脑上的一个文件,在这种情况下,NAME 应该是此文件的绝对路径,包括文件名。默认值
os.path.join(BASE_DIR, 'db.sqlite3')
将会把数据库文件储存在项目的根目录。
如果不使用 SQLite,则必须添加一些额外设置,比如 USER
、 PASSWORD
、 HOST
等等。想了解更多数据库设置方面的内容,请看官方文档:DATABASES
。
注意:
- 若使用 SQLite 以外的数据库,需要在使用前创建好数据库。可以通过数据库的交互式命令行中使用 "
CREATE DATABASE database_name;
" 命令来完成这件事。Django不会自动帮你做这一步工作。- 还要确保
mysite/settings.py
提供的数据库用户具有创建数据库表 即"create database"的权限 。- 如果使用 SQLite,那么无需做任何预先配置——因为数据库会在需要的时候自动创建。
附:
编辑
mysite/settings.py
文件时,顺便设置TIME_ZONE
自己的时区。比如中国时区为 Asia/Shanghai 。此外,注意一下settings.py文件的
INSTALLED_APPS
设置项。这里包括了会在你项目中启用的所有 Django 应用。自己定义创建的app应用都要在这里注册。
1.3. 定义模型类
在 Django 里写一个数据库驱动的 Web 应用的第一步是定义模型 - 也就是数据库结构设计和附加的其它元数据。
模型类定义在models.py文件中,继承自models.Model类。
- 每个模型代表数据库中的一张表
- 每个类的实例代表数据表中的一行数据
- 类中的每个变量代表数据表中的一个字段。每个字段都是
Field
类的实例 - 比如,字符字段被表示为CharField
- 每一个Field实例的名字就是字段的名字
- jango 支持所有常用的数据库关系:多对一、多对多和一对一。如使用
ForeignKey
定义一个外键关系。注意要将外键写在‘多’的一方。
(注:在模型类不需要定义主键列,在生成时会自动添加,并且值为自动增长。)
根据设计,在models.py中定义好了模型类(例子见官方文档),然后还需要进行迁移才能生成相应的数据表。
注:
A和B两个类之间具有一对多的关系,这个一对多的关系应该定义在多的那个类,对应数据表的外键:
属性名 = models.ForeignKey('A类名')
关系属性对应的生成的表的字段名格式:关系属性名_id
1.4. 激活模型
定义模型后,想要使用模型。首先我们得先告诉Django项目,我们要使用相关app应用。然后生成迁移文件,进行迁移。
1.4.1. 注册应用
先告诉Django项目,我们要使用相关app应用。对应用进行注册。
将应用添加到项目中,需要在INSTALLED_APPS
设置中增加指向该应用的配置文件的链接。比如官方文档的投票应用,它的配置类文件PollsConfig是polls/apps.py
,所以它的点式路径为polls.apps.PollsConfig
。将该路径添加到 INSTALLED_APPS
中:
# mysite/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig', # 添加到元组中
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
polls.apps.PollsConfig
可以简写为
polls ,即直接写上应用名。
下一步可以进行迁移了。
1.4.2. 迁移
迁移有两步:
- 生成迁移文件:根据模型类生成创建表的迁移文件。
- 执行迁移:根据第一步生成的迁移文件在数据库中创建表。
- 生成迁移文件命令:
python manage.py makemigrations # 迁移所有
或:
python manage.py makemigrations 应用名
执行生成迁移文件命令后,会在应用的目录下的migrations目录中生成迁移文件。
- 执行迁移命令如下:
python manage.py migrate
当执行迁移命令后,Django框架会读取迁移文件自动帮我们在数据库中生成对应的表格。
注:migrate命令将遍历
INSTALLED_APPS
设置中的所有项目,在数据库中创建对应的表,并打印出每一条动作信息。如果你感兴趣,可以在你的数据库命令行下输入:\dt
(PostgreSQL)、SHOW TABLES;
(MySQL)或.schema
(SQLite) 来列出 Django 所创建的表。
注:生成的数据表的默认名称
<app_name>_<model_name>
应用名_模型名 (小写)
例:
polls_choice
小结:修改模型时的操作分三步:
- 在models.py中修改模型;
- 运行
python manage.py makemigrations
为改动创建迁移记录(迁移文件); - 运行
python manage.py migrate
,将操作同步到数据库。
1.5. 使用模型API操作数据表
完成数据表的迁移之后,就可以通过进入项目的shell,进行简单的API操作。如果需要退出项目,可以使用ctrl+d快捷键或输入quit()。
进入项目python命令行shell的命令(使用pycharm时在Terminal输入即可):
python manage.py shell
进入命令行后,可以基于官方文档的例子练习一下 database API :
>>> from polls.models import Question, Choice # 导入我们写的模型类
# 现在系统内还没有questions对象
>>> Question.objects.all()
<QuerySet []>
# 创建一个新的question对象
# Django推荐使用timezone.now()代替python内置的datetime.datetime.now()
# 这个timezone就来自于Django的依赖库pytz
from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# 你必须显式的调用save()方法,才能将对象保存到数据库内
>>> q.save()
# 默认情况,你会自动获得一个自增的名为id的主键
>>> q.id
1
# 通过python的属性调用方式,访问模型字段的值
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# 通过修改属性来修改字段的值,然后显式的调用save方法进行保存。
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() 用于查询数据库内的所有questions
>>> Question.objects.all()
<QuerySet [<Question: Question object>]>
这里发现上面返回的<Question: Question object>
可读性低,没什么用。这
可以通过
给模型增加 __str__()
方法来解决,提高可读性。这能使命令行里使用带来方便,Django 自动生成的 admin 里也使用这个方法来表示对象。
如给模型Question增加__str__方法(详见官方文档):
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
小结:
导入模型类后,
- 增:定义对象,增加实例属性,用 实例对象.save() ;
- 获取数据:
- 类名.objects.get(查询条件) ,会将查到的数据保存在一个对象,将对象返回 ;
- 查询所有:类名.objects.all()
- 关系为由一类查多类:一类的对象名.多类名_set.all()
- 由多类查询一类:多类对象名.关系属性
- 更新:假设对象已经对应了表的一条数据,对象.属性= ,再对象.save() ;
- 给关系属性赋值时,给它赋值的是跟他关联的对象。
- 删除:对象.delete()
API会自动进行连表操作,通过双下划线分割关系对象。连表操作可以无限多级,一层一层的连接。
如果迁移出错了,可以把迁移文件和数据库删了,重新操作。但是有重要数据时不能这样做。
根据官方文档:
- 数据库 API 的所有细节可以在 数据库 API 参考 文档中找到。
- 阅读 访问关系对象 文档可以获取关于数据库关系的更多内容。
- 想知道关于双下划线的更多用法,参见 查找字段 文档。
2. admin后台管理站点
很多时候,我们不光要开发针对客户使用的前端页面,还要给后台管理人员提供相应的管理界面。Django 可以全自动地根据模型创建后台界面。
使用Django的管理模块,需要按照如下步骤操作:
- 1.管理界面本地化
- 2.创建管理员
- 3.注册模型类
- 4.自定义管理页面
2.1. 管理界面本地化
本地化是将显示的语言、时间等使用本地的习惯。
打开项目的settings.py文件,找到语言编码、时区的设置项,将内容改为如下:
LANGUAGE_CODE = 'zh-hans' #使用中国语言
TIME_ZONE = 'Asia/Shanghai' #使用中国上海时间
2.2. 创建一个管理员账号
创建admin站点的管理员用户的命令如下:
python manage.py createsuperuser
然后按提示输入用户名、邮箱、密码。
Django 的管理界面默认就是启用的。如果开发服务器未启动,用以下命令
启动服务器:
python manage.py runserver
服务器启动后,打开浏览器,转到你本地域名的 "/admin/" 目录, -- 比如 "http://127.0.0.1:8000/admin/" 。你应该会看见管理员登录界面:
注:
在实际环境中,为了站点的安全性,我们一般不能将管理后台的url随便暴露给他人,不能用
/admin/
这么简单的路径。打开根url路由文件
mysite/urls.py
,修改其中admin.site.urls对应的表达式,换成你想要的,比如:from django.contrib import admin from django.urls import path urlpatterns = [ path('polls/', include('polls.urls')), path('control/', admin.site.urls), ]
这样,我们必须访问
http://127.0.0.1:8000/control/
才能进入admin界面。
2.3. 注册模型类
用刚刚的账户登陆后,会看到 Django 管理页面的索引页。当前只有两个可编辑的内容:groups和users(组和用户)。它们是django.contrib.auth
模块提供的身份认证框架。
默认没有我们创建的应用中定义的模型类,需要在自己应用中的admin.py文件中注册,才可以在后台管理中看到,并进行增删改查操作。
比如 问题 Question
对象需要被管理,则打开polls/admin.py
文件,加入下面的内容:
- 导入模型
- 注册模型 admin.site.register(模型名)
from django.contrib import admin
from .models import Question
admin.site.register(Question)
在浏览器中刷新页面,可以看到模型类的管理。
点击模型名,比如“Questions”。即可进入模型(如questions)的修改 列表页。这个页面会显示所有的数据库内的模型(如questions)对象,你可以在这里对它们进行修改。
注意事项:
- 这个表单是从问题模型(如例子的
Question
)中自动生成的- 不同的字段类型(日期时间字段
DateTimeField
、字符字段CharField
)会生成对应的 HTML 输入控件。每个类型的字段都知道它们该如何在管理页面里显示自己。即不同的模型字段类型(DateTimeField, CharField)会表现为不同的HTML input
框类型。- 每个日期时间字段
DateTimeField
都有 JavaScript 写的快捷按钮。日期有转到今天(Today)的快捷按钮和一个弹出式日历界面。时间有设为现在(Now)的快捷按钮和一个列出常用时间的方便的弹出式列表。
2.4.自定义管理页面
默认在列表页只显示出了一个对象的属性,对象的其它属性并没有列出来,查看非常不方便。 Django提供了自定义管理页面的功能,比如列表页要显示哪些值。
在admin.py文件,自定义类,继承自admin.ModelAdmin类。
- 属性list_display表示要显示哪些属性
class QuestionInfoAdmin(admin.ModelAdmin):
list_display = ['question_text', 'pub_date']
- 修改模型类Question的注册代码如下
admin.site.register(Question, QuestionInfoAdmin)
- 刷新Question的列表页,所有属性都显示出来了
-----end-----