Djangon第五篇-----模型详解

目录

前言

配置数据库

使用 Python 定义模型的好处

创建模型

数据的基本访问

插入和更新数据

 过滤数据

 检索单个对象

排序数据

 链式查找

 切片数据

在一个语句中更新多个对象

 删除对象


前言

对现代的 Web 应用程序而言,视图逻辑经常需要与数据库交互。在数据库驱动型网站中,网站连接数据库服务器,从中检索数据,然后在网页中把数据显示出来。此外,可能还会提供让访客自行填充数据库的方式。Django 非常适合构建数据库驱动型网站,它提供了简单而强大的工具,易于使用 Python 执行数据库查询。下面就说明这个功能,即 Django 的数据库层。

配置数据库

settings.py

# Database
# ...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

• ENGINE 告诉 Django 使用哪个数据库引擎。本书的示例使用 SQLite,因此不用改,继续使用默认的
django.db.backends.sqlite3 。
• NAME 告诉 Django 数据库的名称。例如: 'NAME': 'mydb', 。

使用 Python 定义模型的好处

内省(introspection)有开销,而且不完美。为了提供便利的数据访问 API,Django 需要以某种方式知晓数据库布局,而这一需求有两种实现方式。第一种是使用 Python 明确描述数据,第二种是在运行时内省数据库,推知数据模型。第二种方式在一个地方存储表的元数据,看似更简单,其实会导致几个问题。首先,运行时内省数据库肯定有消耗。如果每次执行请求,或者只是初始化 Web 服务器都要内省数据库,那带来的消耗是无法接受的。(有些人觉那点消耗不算事,然而 Django 的开发者可是在想方设法努力降低框架的消耗。)其次,有些数据库,尤其是旧版 MySQL,存储的元数据不足以完成内省。
• Python 编写起来让人心情舒畅,而且使用 Python 编写所有代码无需频繁让大脑切换情境。在一个编程环境(思维)中待久了,有助于提升效率。在 SQL 和 Python 之间换来换去容易打断状态
• 把数据模型保存在代码中比保存在数据库中易于做版本控制,易于跟踪数据布局的变化。
• SQL 对数据布局的元数据只有部分支持。例如,多数数据库系统没有提供专门表示电子邮件地址或URL 的数据类型。而 Django 模型有。高层级的数据结构有助于提升效率,让代码更便于复用。
• 不同数据库平台使用的 SQL 不一致。分发 Web 应用程序时,更务实的做法是分发一个描述数据布局的 Python 模块,而不是分别针对MySQL、PostgreSQL 和 SQLite 的 CREATE TABLE 语句。

创建模型

在编译器命令行执行或定位到项目根目录

django-admin startapp books

models.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()
class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()
class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

 settings.py 添加books模型

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'books',
)

检查框架,如下即可

python manage.py check

确认模型有效之后,运行下述命令,告诉 Django 你对模型做了修改(这里是新建了模型):

python manage.py makemigrations books

Django 把对模型(也就是数据库模式)的改动存储在迁移中,迁移就是磁盘中的文件。运行上述命令后,books 应用的 migrations 文件夹里会出现一个名为 0001_initial.py 的文件。 migrate 命令会查看最新的迁移文件,自动更新数据库模式;不过,我们先来看看将运行的 SQL。 sqlmigrate 命令的参数是迁移名称,输出的结果是对应的 SQL:

python manage.py sqlmigrate books 0001

• 自动生成的表名结合应用的名称( books )和模型名的小写形式( publisher 、 book 和 author )。
• 前面说过,Django 会自动为各个表添加主键,即 id 字段。这个行为可以覆盖。按约定,Django 在外键字段的名称后面加上 "_id" 。你可能猜到了,这个行为也可以覆盖。
• 外键关系通过 REFERENCES 语句指明。

sqlmigrate 命令并不创建表,其实它根本不接触数据库,而是在屏幕上输出 Django 将执行的 SQL。如果愿意,可以把输出的 SQL 复制粘贴到数据库客户端里,然而,Django 为提交 SQL 提供了更为简单的方式

python manage.py migrate

数据的基本访问

创建模型之后,Django 自动提供了操作模型的高层 Python API。运行 python manage.py shell ,输入下述代码试试:

>>> from books.models import Publisher
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/')
>>> p1.save()
>>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',
... city='Cambridge', state_province='MA', country='U.S.A.',
... website='http://www.oreilly.com/')
>>> p2.save()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]

主要功能如下:

• 首先,导入 Publisher 模型类,以便与保存出版社的数据库表交互。
• 提供各个字段的值, name 、 address ,等等,实例化一个 Publisher 对象。
• 为了把对象保存到数据库中,调用 save() 方法。Django 在背后执行 SQL INSERT 语句。
• 为了从数据库中检索出版社,使用 Publisher.objects 属性,你可以把它的值理解为全部出版社。使用 Publisher.objects.all() 获取数据库中的所有 Publisher 对象。Django 在背后执行 SQL SELECT 语句

使用 Django 模型 API 创建的对象不会自动保存,只能自己动手调用 save() 方法

为 Publisher 类添加一个名为 __str__() 的方法可改变publisher_list输出内容,如

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()
    def __str__(self):
        return self.name

插入和更新数据

>>> from books.models import Publisher
>>> p = Publisher(name='1',address='qwe',city ='bb',state_province='ca',country='usa',website='sda')
>>> p.save()
>>> p.id
1
>>> p.id = 111
>>> p.id
111
>>> p.save()

 过滤数据

也可以传递多个参数

>>> Publisher.objects.filter(id=1)
<QuerySet [<Publisher: 1>]>

 检索单个对象

>>> Publisher.objects.get(id=1)
<Publisher: 1>

排序数据

 Publisher.objects.order_by("name")

多个字段排序(以第一个字段排不出顺序时使用第二个字段),提供多个参数:

>>> Publisher.objects.order_by("state_province", "address")

反向排序。方法是在字段名称前面加上“-”(减号):

Publisher.objects.order_by("-name")

 链式查找

过滤数据同时排序数据

 Publisher.objects.filter(country="U.S.A.").order_by("-name")

 切片数据

只显示第一个

 Publisher.objects.order_by('name')[0]

范围切片

 Publisher.objects.order_by('name')[0:2]

注意,不支持使用负数:可以换成一下形式

 Publisher.objects.order_by('-name')[0]

在一个语句中更新多个对象

 Publisher.objects.filter(id=52).update(name='Apress Publishing')
 Publisher.objects.all().update(country='USA')

 删除对象

删除所有

 Publisher.objects.all().delete()

删除部分

 Publisher.objects.filter(country='USA').delete()

猜你喜欢

转载自blog.csdn.net/Da___Vinci/article/details/84313812