Django模型与数据库的使用
一、设置数据库
1.新建项目后应该告诉 Django 你想用什么数据库(settings.py 模块中的 DATABASES 设置)。
使用sqllite3数据库:
使用mysql数据库的配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mybook',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306'
}
}
注:使用mysql数据库需要在项目的__init__下导入如下包,才可使用
import pymysql
pymysql.install_as_MySQLdb()
二、创建模型
在 settings.py 模块中配置好数据库之后,下面创建rango应用所需的两个数据模型。Django 应用的模型保存在应用目录中的 models.py 模块里。因此,Rango 应用的模型保存在 rango/models.py文件中。我们要定义两个类,一个类对应一个模型。这两个类都要继承基类 django.db.models.Model,分别表示分类和网页。参照下述代码片段定义 Category 和 Page 模型。
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
def __str__(self): # Python 2 还要定义 __unicode__
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): # Python 2 还要定义 __unicode__
return self.titl
定义模型时,要指定字段及其类型,并提供必须或可选的参数。默认情况下,每个模型都有一个自增整数字段,名为 id。这个字段自动分配,用作主键。
Django 内置的字段类型无所不包。下面介绍其中最常用的几个:
❏ CharField:存储字符数据(如字符串)的字段。max_length 参数指定最多可存储的字符
数。
❏ URLField:类似于 CharField,不过是专用于存储 URL 的。也可指定 max_length 参数。
❏ IntegerField:存储整数。
❏ DateField:存储 Python datetime.date 对象。
为了建立模型之间的关系,Django 提供了三个字段类型,分别是:
❏ ForeignKey:用于建立一对多关系。
❏ OneToOneField:用于建立一对一关系。
❏ ManyToManyField:用于建立多对多关系。
添加模型的过程可以分为以下 5 步。
1.首先在 Django 应用的 models.py 文件中定义模型。
2. 更新 admin.py,注册新增的模型。
3. 生成迁移:python manage.py makemigrations <app_name>。
4. 运行迁移:python manage.py migrate。在数据库中创建模型所需的表和字段。
5. 创建或编辑填充脚本。
三、创建和迁移数据库
在 models.py 中定义好模型之后,可以让 Django 施展魔法,在底层数据库中创建表了。为此,Django 提供了迁移工具,让它帮助我们设置和更新数据库,体现模型的改动。例如,添加新字段后可以使用迁移工具更新数据库。
python manage.py makemigrations rango
如果想查看 Django ORM 为某个迁移执行的底层 SQL,可以执行下述命令:
python manage.py sqlmigrate rango 0001
创建好迁移后,要提交到数据库。为此要再次执行 migrate 命令。
python manage.py migrate
上述命令执行完毕后,rango/migrations 目录中会出现一个 Python 脚本,名为 0001_initial.py。这个脚本中包含此次迁移创建数据库模式所需的一切信息。
注:若有时新增了模型中的字段,此时可能需要删除数据库以及每个应用migrate文件夹下的迁移生成的文件__0001__inital.py(不删除__init__.py),重头执行上面的步骤。
四、配置管理界面
Django 广受欢迎的一个功能是内置的 Web 管理界面,在这里你可以浏览、标记和删除模型实例表示的数据。
打开 Web 浏览器,访问 http://127.0.0.1:8000/admin/。你会看到登录界面。使用创建超级用户时提供的凭据登录。
修改默认的Django标题
admin.site.site_header = '我在左上角'
admin.site.site_title = '我在浏览器标签'
admin.site.index_title = '我在后台首页'
为了显示上述我们模型创建的 Category 和 Page 这两个模型,我们要给Django 一些提示。打开 rango/admin.py 文件,注册想在管理界面显示的类。下述代码注册 Category 和 Page 两个类。
from django.contrib import admin
from rango.models import Category, Page
admin.site.register(Category)
admin.site.register(Page)
2.此外,还可以在 admin.py 模块中注册模型,以便在管理界面中管理。
from django.contrib import admin
from rango.models import Category, Page
class CategoryAdmin(admin.ModelAdmin): #定制管理员界面
list_display = ['name', 'views', 'likes'] #在管理员界面中显示的字段
preserve_filters = {'sulg': ('name',)}
class PageAdmin(admin.ModelAdmin):
list_display = ['title', 'url', 'views']
admin.site.register(Category, CategoryAdmin)
admin.site.register(Page, PageAdmin)
如果以后添加更多模型,只需再调用 admin.site.register() 方法。
四、编写一个填充脚本
创建或编辑填充脚本。可以在开发测试阶段为数据库添加测试数据,以免删除数据库后需要手动录入数据。如下:
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():
# 首先创建一些字典,列出想添加到各分类的网页
# 然后创建一个嵌套字典,设置各分类
# 这么做看起来不易理解,但是便于迭代,方便为模型添加数据
python_pages = [
{"title": "Official Python Tutorial",
"url": "http://docs.python.org/2/tutorial/",
'views': 32},
{"title": "How to Think like a Computer Scientist",
"url": "http://www.greenteapress.com/thinkpython/", 'views': 16},
{"title": "Learn Python in 10 Minutes",
"url": "http://www.korokithakis.net/tutorials/python/", 'views': 8}]
django_pages = [
{"title": "Official Django Tutorial",
"url": "https://docs.djangoproject.com/en/1.9/intro/tutorial01/", 'views': 32},
{"title": "Django Rocks",
"url": "http://www.djangorocks.com/", 'views': 16},
{"title": "How to Tango with Django",
"url": "http://www.tangowithdjango.com/", 'views': 8}]
other_pages = [
{"title": "Bottle",
"url": "http://bottlepy.org/docs/dev/", 'views': 16},
{"title": "Flask",
"url": "http://flask.pocoo.org", 'views': 8}]
cats = {"Python": {"pages": python_pages, 'views': 128, 'likes': 64},
"Django": {"pages": django_pages, 'views': 64, 'likes': 32},
"Other Frameworks": {"pages": other_pages, 'views': 32, 'likes': 16}}
# 如果想添加更多分类或网页,添加到前面的字典中即可
# 下述代码迭代 cats 字典,添加各分类,并把相关的网页添加到分类中
# 如果使用的是 Python 2.x,要使用 cats.iteritems() 迭代
# 迭代字典的正确方式参见
# http://docs.quantifiedcode.com/python-anti-patterns/readability/
# print("+++++++++++", cats.items())
for cat, cat_data in cats.items():
c = add_cat(cat, cat_data['views'], cat_data['likes'])
for p in cat_data["pages"]:
add_page(c, p["title"], p["url"], p['views'])
# 打印添加的分类
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,views=0,likes=0):
c = Category.objects.get_or_create(name=name, views=views, likes=likes)[0]
c.save()
return c
# 从这开始执行
if __name__ == '__main__':
print("Starting Rango population script...")
populate()