数据库配置
现在,打开 mysite/settings.py
。这是个包含了 Django 项目设置的 Python 模块。
通常,这个配置文件使用 SQLite 作为默认数据库。如果你不熟悉数据库,或者只是想尝试下 Django,这是最简单的选择。Python 内置 SQLite,所以你无需安装额外东西来使用它。当你开始一个真正的项目时,你可能更倾向使用一个更具扩展性的数据库,例如 PostgreSQL,避免中途切换数据库这个令人头疼的问题。
如果你想使用其他数据库,你需要安装合适的 database bindings ,然后改变设置文件中 DATABASES
'default'
项目中的一些键值:
ENGINE
— 可选值有'django.db.backends.sqlite3'
,'django.db.backends.postgresql'
,'django.db.backends.mysql'
,或'django.db.backends.oracle'
。其它 可用后端。NAME
- 数据库的名称。如果使用的是 SQLite,数据库将是你电脑上的一个文件,在这种情况下,NAME
应该是此文件的绝对路径,包括文件名。默认值os.path.join(BASE_DIR, 'db.sqlite3')
将会把数据库文件储存在项目的根目录。
编辑 mysite/settings.py
文件前,先设置 TIME_ZONE
为你自己时区,(中国时区为+8)
此外,关注一下文件头部的 INSTALLED_APPS
设置项。这里包括了会在你项目中启用的所有 Django 应用。应用能在多个项目中使用,你也可以打包并且发布应用,让别人使用它们。
通常, INSTALLED_APPS
默认包括了以下 Django 的自带应用:
django.contrib.admin
— 管理员站点, 你很快就会使用它。django.contrib.auth
— 认证授权系统。django.contrib.contenttypes
— 内容类型框架。django.contrib.sessions
— 会话框架。django.contrib.messages
— 消息框架。django.contrib.staticfiles
— 管理静态文件的框架。
默认开启的某些应用需要至少一个数据表,所以,在使用他们之前需要在数据库中创建一些表。请执行以下命令:
python manage.py migrate
这个 migrate
命令检查 INSTALLED_APPS
设置,为其中的每个应用创建需要的数据表,至于具体会创建什么,这取决于你的mysite/settings.py 设置文件和每个应用的数据库迁移文件.
总体来说总结为三个部分
- 编辑 **
models.py
文件,改变模型。创建模型** - 在polls\models.py文件中编入以下代码
• from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
- 运行** [
python manage.py makemigrations
](https://docs.djangoproject.com/zh-hans/3.0/ref/django-admin/#django-admin-makemigrations) 为模型的改变生成迁移文件。激活模型** - 为这个应用创建数据库 schema(生成
CREATE TABLE
语句)。 - 创建可以与
Question
和Choice
对象进行交互的 Python 数据库 API 为了在我们的工程中包含这个应用,我们需要在配置类
INSTALLED_APPS
中添加设置。因为PollsConfig
类写在文件polls/apps.py
中,所以它的点式路径是'polls.apps.PollsConfig'
。在文件mysite/settings.py
中INSTALLED_APPS
子项添加点式路径后,它看起来像这样:INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
这样我们的Django项目就会包含了polls应用,接下来我们还需要在cmd(powershell)中输入python manage.py makemigrations polls来对我们的模型文件进行一次修改,并对修改部分存储为一次迁移
- Django 有一个自动执行数据库迁移并同步管理你的数据库结构的命令 - 这个命令是
migrate
,我们马上就会接触它 - 但是首先,让我们看看迁移命令会执行哪些 SQL 语句。sqlmigrate
命令接收一个迁移的名称,然后返回对应的 SQL:在cmd(powershell)中输入python manage.py sqlmigrate polls **0001** - 当你对你的步骤有问题时可以输入python manage.py check 来检查项目中的问题
- 运行
python manage.py migrate
来应用数据库迁移。 - 现在再次输入python manage.py migrate在数据库里创建新定义的模型的数据表
初试API
models文件最后如下,不然容易出错
from django.db import models
import datetime
from django.utils import timezone
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):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
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
打开目录输入py manage.py shell打开python命令交互行
>>> from polls.models import Choice, Question # Import the model classes we just wrote.
# 系统中尚无问题。
>>> Question.objects.all()
<QuerySet []>
# 创造一个新问题
# 在默认设置文件中启用了对时区的支持
# Django期望的约会时间,选择现在所使用的的时区
# 用正确的时区去替代默认的时区,这会帮助你很多
>>> 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()来显示数据库中的所有问题.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
<Question: Question object (1)>
对于我们了解这个对象的细节没什么帮助。让我们通过编辑 Question
模型的代码(位于 polls/models.py
中)来修复这个问题。给 Question
和 Choice
增加 __str__()
方法。具体参考第一段
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
给模型增加 __str__()
方法是很重要的,这不仅仅能给你在命令行里使用带来方便,Django 自动生成的 admin 里也使用这个方法来表示对象。
让我们再为此模型添加一个自定义方法
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
保存文件然后通过 py manage.py shell 命令再次打开 Python 交互式命令行:
>>> from polls.models import Choice, Question
# 确保我们的__str __()添加成功.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
# Django 提供丰富的数据库查找API
# 关键字参数.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
# 获取这次发布的问题.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# 请求一个不存在的ID,这将引发异常.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# 通过主键查找是最常见的情况,因此Django为主键精确查找提供了快捷方式
# 以下与Question.objects.get(id = 1)相同.
>>> Question.objects.get(pk=1)
<Question: What's up?>
# M确保我们的定制方法在工作.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# 给问题几个选择。 create调用构造一个新的Choice对象,执行INSERT语句,
# 将该选择添加到一组可用选项中,并返回新的Choice对象。
# Django创建一个集合来保存ForeignKey关系的“另一面”
# (e.g. a question's choice) 哪个可以通过API访问.
>>> q = Question.objects.get(pk=1)
# 显示相关对象集中的任何选择-到目前为止没有选择.
>>> q.choice_set.all()
<QuerySet []>
# 创造三个选择(机会).
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
# 选择对象可以通过API访问其相关的Question对象.
>>> c.question
<Question: What's up?>
# 反之亦然:问题对象可以访问Choice对象.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
# API会根据您的需要自动遵循关系。
# 使用双下划线分隔关系。
# 这可以根据需要进行任意深度的工作。
# 查找这次pub_date为任何问题的所有选项
# (重用我们在上面创建的'current_year'变量).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# 让我们删除其中一个选项。用delete()来完成这个行为.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
创建一个管理员账户
让我们在cmd(powershell)中输入py manage.py createsuperuser来创造一个用户名
#输入你想要的账号
Username: admin
#输入你想要的的邮箱地址
Email address: admin@example.com
#输入你想要的密码
Password: **********
Password (again): *********
Superuser created successfully.
创建成功后,启动py manage.py runserver来启动我们的服务器
现在,打开浏览器,转到你本地域名的 “/admin/“ 目录, — 比如 “http://127.0.0.1:8000/admin/“ 。你应该会看见管理员登录界面,登入以后我们可以看到管理界面(你将会看到几种可编辑的内容:组和用户。它们是由 django.contrib.auth
提供的,这是 Django 开发的认证框架。)
向管理页面中加入投票应用
接下来我们需要在polls的admin.py文件中加入以下来创建一个可投票选项
from django.contrib import admin
from .models import Question
admin.site.register(Question)
体验便捷的管理功能
在我们向管理页面注册了问题 Question
类。Django 知道它应该被显示在索引页里:点击 “Questions” 。现在看到是问题 “Questions” 对象的列表 “change list” 。这个界面会显示所有数据库里的问题 Question 对象,你可以选择一个来修改。这里现在有我们在上一部分中创建的 “What’s up?” 问题。
击 “What’s up?” 来编辑这个问题(Question)对象
注意事项:
- 这个表单是从问题
Question
模型中自动生成的 - 不同的字段类型(日期时间字段
DateTimeField
、字符字段CharField
)会生成对应的 HTML 输入控件。每个类型的字段都知道它们该如何在管理页面里显示自己。 - 每个日期时间字段
DateTimeField
都有 JavaScript 写的快捷按钮。日期有转到今天(Today)的快捷按钮和一个弹出式日历界面。时间有设为现在(Now)的快捷按钮和一个列出常用时间的方便的弹出式列表。
页面的底部提供了几个选项:
- 保存(Save) - 保存改变,然后返回对象列表。
- 保存并继续编辑(Save and continue editing) - 保存改变,然后重新载入当前对象的修改界面。
- 保存并新增(Save and add another) - 保存改变,然后添加一个新的空对象并载入修改界面。
- 删除(Delete) - 显示一个确认删除页面。
如果显示的 “发布日期(Date Published)” 和你在 教程 1 里创建它们的时间不一致,这意味着你可能没有正确的设置 TIME_ZONE
。改变设置,然后重新载入页面看看是否显示了正确的值。
通过点击 “今天(Today)” 和 “现在(Now)” 按钮改变 “发布日期(Date Published)”。然后点击 “保存并继续编辑(Save and add another)”按钮。然后点击右上角的 “历史(History)”按钮。你会看到一个列出了所有通过 Django 管理页面对当前对象进行的改变的页面,其中列出了时间戳和进行修改操作的用户名: