当你想到数据库时,你通常会想到结构化查询语言(SQL),这是我们查询数据库得到我们需要的数据的常用方法。在Django中,查询底层数据库(可以存储各种数据,比如您网站的用户信息)由对象关系映射器(ORM)负责处理。实质上,存储在数据库表中的数据可以被封装在一个模型。 模型是描述数据库表数据的Python对象。 而不是通过SQL直接在数据库上工作,你只需要操纵对应的Python模型对象。
本章将向您介绍使用Django进行数据管理的基础知识及其ORM。你会发现在你的应用程序底层数据库中添加,修改和删除数据是非常容易的。并且
从数据库获取数据到用户的Web浏览器有多简单。
5.1 Rango的要求
在开始之前,让我们回顾一下我们正在开发的Rango应用程序的数据要求。
应用程序的全部需求在前面详细介绍,但为了让您更好记忆,我们快速总结一下客户的需求。
- Rango本质上是一个网页目录- 包含指向其他网站的链接的网站。
- 有许多不同的网页类别,每个类别的收纳一些链接。我们在概述章节中假设这是一个一对多的关系。 查看该下面的实体关系图。
- 一个类别有名字,访问次数和喜欢数。
- 一个页面是指一个类别,有标题,网址和浏览数。
5.2 告诉Django你的数据库
在我们创建任何模型之前,我们需要用Django来设置我们的数据库。 在Django 1.11中,当你建立一个新的项目,变量DATABASES是在你自动创建的settings.py
模块中。 它会看起来类似于下面的例子:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
5.3 创建模型
在settings.py
中配置好数据库后,让我们为Rango应用创建两个初始数据模型。 Django应用程序的模型存储在相应的models.py
模块。 这意味着对于Rango,模型被存储在内部rango/models.py
定义类别和页面模型如下。
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
def __str__(self):# For Python 2, use __unicode__ too
return self.name
class Page(models.Model):
category=models.ForeignKey(Category)
title=models.CharField(max_length=128)
url=models.URLField()
views=models.IntegerField(default=0)
def __str__(self)# For Python 2, use __unicode__ too
return self.title
定义模型时,需要指定字段及其关联类型的列表以及任何必需或可选参数。默认情况下,所有模型都有一个自动增加的整数x字段,称为id,它被自动分配并作为主键。
Django提供了一系列全面的内置字段类型。 一些最常用的详细如下
-
CharField,用于存储字符数据(例如,字符串)的字段。指定
最长长度,提供一个字段可以存储的最大字符数。 -
URLField,很像CharField,但专为存储资源URL而设计。 你也可以
指定一个最长长度参数。 - IntegerField,存储整数。
- DateField,它存储一个Python datetime.date对象
对于每个字段,您可以指定唯一属性。如果设置为True,则整个数据库模型中只能存在该字段中特定值的一个实例。 例如,看看我们的类别上面定义的模型。字段名称已被设置为唯一 - 因此每个类别名称必须是唯一的。 这意味着您可以像使用主键一样使用该字段。您也可以为每个字段指定其他属性,例如使用语法default ='value'指定默认值,以及字段的值是否为空(或NULL)(null = True)或不是(null = False)。
Django为数据库中的相关模型提供了三种机制,它们是:
- ForeignKey,一种允许我们创建一对多关系的字段类型
- OneToOneField,一种允许我们定义严格的一对一关系的字段类型
- ManyToManyField,允许我们定义多对多关系的字段类型
5.4 创建和迁移数据库
通过在models.py
中定义的模型,我们现在可以让Django发挥其魔力,并在底层数据库中创建表。 Django提供了所谓的迁移工具,帮助我们设置和更新数据库,以反映对模型的任何更改。 例如,如果要添加新字段,则可以使用迁移工具来更新数据库。
配置
首先,数据库必须被初始化。 这意味着创建它和其中的所有关联表,以便数据可以存储在其中。 要做到这一点,你必须打开终端或命令提示符,并导航到你的项目的根目录 - manage.py的存储位置。 运行以下命令。
python manage.py migrate
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying sessions.0001_initial... OK
接下来,创建一个超级用户来管理数据库。 运行以下命令。
C:\Users\XC\PycharmProjects\tango_with_django_project>python manage.py createsuperuser
Username (leave blank to use 'xc'): xc
Email address: XXXXXX@qq.com
Password:
Password (again):
Superuser created successfully.
创建和更新模型/表格
每当你改变你的应用程序的模型,你需要通过manage.py
中的makemigrations命令注册更改
$ python manage.py makemigrations rango
Migrations for 'rango':
rango\migrations\0001_initial.py
- Create model Category
- Create model Page
在为应用程序创建迁移之后,您需要将它们提交到数据库。
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, rango, sessions
Running migrations:
Applying rango.0001_initial... OK
5.5 Django模型和Shell
在我们将注意力转移到演示Django管理界面之前,值得注意的是,您可以直接使用Django shell与Django模型进行交互 - 这是一个非常有用的工具,用于调试目的。 我们将演示如何使用此方法创建一个类别实例。
$ python manage.py shell
Python 3.6.1 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:25:24) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.
IPython 5.3.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: from rango.models import Category
In [2]: print(Category.objects.all)
<bound method BaseManager.all of <django.db.models.manager.Manager object at 0x00000290DF925240>>
In [3]: print(Category.objects.all())
<QuerySet []>
In [4]: c = Category(name ='Test')
In [5]: c.save()
In [6]: print(Category.objects.all())
<QuerySet [<Category: Test>]>
In [7]: quit()
5.6 配置管理界面
$ python manage.py runserver
点击http://127.0.0.1:8000/admin/,用之前注册的用户名和密码登陆。为了在界面中包含类别和界面模块,修改rango/admin.py
。
from django.contrib import admin
from rango.models import Category,Page
# Register your models here.
admin.site.register(Category)
admin.site.register(Page)
5.7 创建一个填充脚本
将测试数据输入到数据库往往是一件麻烦事。 许多开发者会通过随机点击密钥来添加一些伪造的测试数据,就像wTFzm8j3z7一样。
比起这样,最好编写一个脚本,以便你和你的合作者使用相同的测试数据。 此外,这种方法将保证你有有用的和伪现实的数据,而不是随机的垃圾。因此,为您的应用程序创建所谓的填充脚本是一个很好的做法。 此脚本旨在自动为您的数据库填充测试数据。
为了Rango创建一个填充脚本,首先你在项目的根目录下创建
populate_rango.py
文件并添加下面的代码。
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','tango_with_django_project.settings')
import django
django.setup()
from rango.models import Category,Page
def populate():
# First, we will create lists of dictionaries containing the pages
# we want to add into each category.
# Then we will create a dictionary of dictionaries for our categories.
# This might seem a little bit confusing, but it allows us to iterate
# through each data structure, and add the data to our models.
python_pages = [
{"title":"Official Python Tutorial",
"url":"http://docs.python.org/2/tutorial/",},
{"title":"How to Think like a Computer Scientist",
"url": "http://www.greenteapress.com/thinkpython/",},
{ "title": "Learn Python in 10 Minutes",
"url": "http://www.korokithakis.net/tutorials/python/", }]
django_pages = [
{"title": "Official Python Tutorial",
"url": "https://docs.djangoproject.com/en/1.9/intro/tutorial01/", },
{"title": "Django Rocks",
"url": "http://www.djangorocks.com/", },
{"title": "How to Tango with Django",
"url": "http://www.tangowithdjango.com/",}
]
other_pages = [
{"title": "Bottle",
"url": "http://bottlepy.org/docs/dev/", },
{"title": "Flask",
"url": "http://flask.pocoo.org", }
]
cats ={
"Python":{ "pages":python_pages},
"Django":{"pages":django_pages},
"Other Frameworks":{"pages":other_pages},
}
# The code below goes through the cats dictionary, then adds each category,
# and then adds all the associated pages for that category.
# if you are using Python 2.x then use cats.iteritems() see
# http://docs.quantifiedcode.com/python-anti-patterns/readability/
# for more information about how to iterate over a dictionary properly.
for cat, cat_data in cats.items():
c = add_cat(cat)
for p in cat_data["pages"]:
add_page(c,p["title"],p["url"])
#print out the categories we have added.
for c in Category.objects.all():
for p in Page.objects.filter(category=c):
print("-{0} -{1}".format(str(c),str(p)))
def add_page(cat,title,url,views = 0):
p = Page.objects.get_or_create(category =cat,title =title)[0]
p.url = url
p.views = views
p.save()
return p
def add_cat(name):
c = Category.objects.get_or_create(name = name)[0]
c.save()
return c
#Start execution here!
if __name__ == '__main__':
print("Starting rango population script...")
populate()
执行
python populate_rango.py
Starting rango population script...
-Python -Official Python Tutorial
-Python -How to Think like a Computer Scientist
-Python -Learn Python in 10 Minutes
-Django -Official Python Tutorial
-Django -Django Rocks
-Django -How to Tango with Django
-Other Frameworks -Bottle
-Other Frameworks -Flask
接下来,验证填充脚本实际填充数据库。 重新启动Django开发服务器,导航到管理界面(http://127.0.0.1:8000/admin/rango/page/),并检查你有一些新的类别和页面。
5.8 工作流程:模型设置
设置您的数据库
有了一个新的Django项目,你应该首先告诉Django你打算使用的数据库(即在settings.py配置DATABASES)。 你也可以在admin.py中注册任何你的应用程序模型模块,使他们可以通过管理界面访问。
添加模板
五步
- 1 首先,在Django应用程序的
models.py
文件中创建新的模型。 - 2 更新admin.py来包含并注册您的新模型。
- 3 执行迁移 $ python manage.py makemigrations <app_name>
- 4 应用更改 $ python manage.py migrate。 这将为您的新模型在数据库中创建必要的基础设施。
- 5 为你的新模型创建/编辑填充脚本。
总有一天,你将不得不删除你的数据库。 发生这种情况时,从manage.py
模块运行下面的命令.
1 . 迁移你的数据库 - 这将在新的数据库中设置一切。 确保您的应用程序在提交的迁移中列出。 如果不是,请运行makemigrations <appname>命令
2 .使用创建超级用户命令创建一个新的管理帐户。