六:Models示例

Django本身提供了非常强大易使用的ORM组件,并且支持多种数据库。

配置连接数据文件

在自己创建的project 目录下编辑settings.py

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # mysql 数据库
'NAME': 'dbname', #确保此数据库已存在
'HOST':'',
'PORT':'',
'USER':'root',
'PASSWORD':''
}
}

 

假设下面的概念,字段关系:

1,一个作者有姓,名及email地址

2,出版商有名称,地址,所在城市,省,国家,网站

3,书籍有书名和出版日期。它有一个或多个作者,只有一个出版商

#models.py
# 一张表定义一个类,这里不再需要单独定义关联表 from django.db import models 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()

模型安装

代码完成后,就需要创建表了。

第一步,在Django项目中 激活这些模型。将上面的模型所在的app添加到配置文件的安装应用列表中。

# settings.py

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
   'app01', # 自己所创建的Django项目名
)

 

按照模型的配置生成表结构

命令行模式:

python manage.py makemigrations                    # 生成同步记录

python manage.py migrate                                 # 开始同步数据库

 

基本数据访问

数据同步完成之后就可以在命令行模式 使用 python manage.py shell 就可以进入Django提供的高级python API

>>> 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>]

如果需要一步创建与存储到数据库,就需要使用 objects.create() 方法

>>> p1 = Publisher.objects.create(name='Apress',
... address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/') # 直接写如数据库
>>> p2 = Publisher.objects.create(name="O'Reilly",
... address='10 Fawcett St.', city='Cambridge',
... state_province='MA', country='U.S.A.',
... website='http://www.oreilly.com/')
>>> publisher_list = Publisher.objects.all()
>>> publisher_list

 

__unicode__() 和 __str__()

当我们打印整个publisher 列表时,我们没有得到想要的信息,无法把对象区分。

[<Publisher: Publisher object>, <Publisher: Publisher object>]

为了解决这个问题,只需要为publisher对象添加一个方法。这个方法告诉python 如果将对象以unicode的方式显示出来。

def __str__(self):
return self.name
# name为需要显示的字段名。可以返回多个
# return "<%s %s>" %(self.first_name,self.last_name)

注:在python 2.x 里面使用 __unicode_()  python3.x 里面使用 __str__()

插入和更新数据

插入数据:

p = Publisher(name='Apress',
... address='2855 Telegraph Ave.',
... city='Berkeley',
... state_province='CA',
... country='U.S.A.',
... website='http://www.apress.com/') p.save() # 这一步才会插入数据库

更新数据:

>>> p.name = 'Apress Publishing'    # 直接赋值,就是更改数据
>>> p.save() # 保存

 

查找对象

>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
# 相当于SQL 语句
SELECT id, name, address, city, state_province, country, website
FROM books_publisher;

注意:Django 在选择所有数据时并没有使用 select * ,而是显示列出了所有字段。因为 select * 会更慢,而且最重要的是列出所有字段遵循了python 界的一个信条:明言胜于暗示

数据过滤

filter() 方法进行数据过滤

>>> Publisher.objects.filter(name='Apress')
[<Publisher: Apress>]

可以使用多个 filter() 来缩小范围:

>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")
[<Publisher: Apress>]

进行模糊匹配:

>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
# 在name和contains 之间有两个下划线。

# Django 使用双下划线来表明会进行一些操作。

转为原生的SQL:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name LIKE '%press%';

 

获取单个对象

使用get() 方法获取单个对象

>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>

这里返回的是单个对象,而不是列表。所以如果结果是多个对象,就会导致抛出异常。

如果没有查询到结果也会抛出异常:

>>> Publisher.objects.get(name="Penguin")
Traceback (most recent call last):
...
DoesNotExist: Publisher matching query does not exist.

这个DoesNotExist 异常是 publisher 这个model 类的一个属性,即publisher.DoesNotExist。在应用中可以捕获并处理这个异常。

try:
p = Publisher.objects.get(name='Apress')
except Publisher.DoesNotExist:
print "Apress isn't in the database yet."
else:
print "Apress is in the database."

数据排序

使用order_by() 方法进行排序

>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]

对多个字段进行排序

>>> Publisher.objects.order_by("state_province", "address")
[<Publisher: Apress>, <Publisher: O'Reilly>]

倒序,在前面加一个 - 前缀:

>>> Publisher.objects.order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]

尽管和灵活,但是每次都要用 order_by() 显得有点啰嗦。大多数只会通过某些字段进行排序,这中情况下Django 可以指定模型的缺省排序方式:

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 __unicode__(self):
return self.name class Meta:
ordering = ['name']
# 缺省排序字段

class Meta ,内嵌于Publisher这个类的定义中(如果class Publisher是顶格的,那么class Meta 在它之下不要缩进4个空格)。可以在任意一个模型中使用Meta类,来设置一些与特定模型相关的选择。Meta 还可以设置其他选项。如果设置了这个选项,那么触发检索时特意额外使用了 order_by() ,否则,当你使用Django的数据库API去检索时,Publisher对象的相关返回值默认都会按照name字段排序。

连锁查询

同时进行过滤和排序查询

>>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]

限制返回的数据

只显示第一条数据

>>> Publisher.objects.order_by('name')[0]
<Publisher: Apress>

[ ] 内类似一个列表

比如取第一条和第二条

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

但是不支持 负索引

更新多个对象

在插入和更新数据中,使用save()方法,这个方法会更新一行里面的说有列。

>>> p = Publisher.objects.get(name='Apress')
>>> p.name = 'Apress Publishing'
>>> p.save() # 原生的SQL语句:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = 'Apress'; UPDATE books_publisher SET
name = 'Apress Publishing',
address = '2855 Telegraph Ave.',
city = 'Berkeley',
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 52;
#假设ID为52

从原生的SQL来看save() 方法是更新了一行内的所有字段。

如果想只更新某一个字段

>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')

转为的原生SQL

UPDATE books_publisher
SET name = 'Apress Publishing'
WHERE id = 52;

update()方法对任何结果集都有效。因此可以同时更新多条记录

>>> Publisher.objects.all().update(country='USA')
2 #update()方法会返回一个整数数值,表示受到影响的记录条数。

删除对象

使用delete()方法

>>> p = Publisher.objects.get(name="O'Reilly")
>>> p.delete()
>>> Publisher.objects.all()
[<Publisher: Apress Publishing>] # 同也可以删除多条数据
>>> Publisher.objects.filter(country='USA').delete()
>>> Publisher.objects.all().delete()
>>> Publisher.objects.all()
[]

在删除数据的时候要小心,一旦使用all()方法,所有的数据将会被删除。

如果需要删除部分的数据,就不需要调用all()方法。

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

Django基础(二)—— models的更多相关文章

  1. day 66 Django基础二之URL路由系统

    Django基础二之URL路由系统   本节目录 一 URL配置 二 正则表达式详解 三 分组命名匹配 四 命名URL(别名)和URL反向解析 五 命名空间模式 一 URL配置 Django 1.11 ...

  2. day 53 Django基础二之URL路由系统

    Django基础二之URL路由系统   本节目录 一 URL配置 二 正则表达式详解 三 分组命名匹配 四 命名URL(别名)和URL反向解析 五 命名空间模式 一 URL配置 Django 1.11 ...

  3. Django基础二静态文件和ORM

    Django基础二静态文件和ORM 目录 Django基础二静态文件和ORM 1. 静态文件 1.1 静态文件基本配置: 1.2 静态文件进阶配置 2. request参数 3. Django配置数据 ...

  4. Django基础二之URL路由系统

    一 URL配置 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表.你就是以这 ...

  5. python 自动化之路 day 19 Django基础[二]

    Django - 路由系统 url.py - 视图函数 views.py - 数据库操作 models.py - 模板引擎渲染 - HttpReponse(字符串) - render(request, ...

  6. 02.Django基础二之URL路由系统

    一 URL配置 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表.你就是以这 ...

  7. Django基础-002 Models的属性与字段

    1.models字段类型 AutoField():一个IntegerField,根据可用ID自动递增.如果没指定主键,就创建它自动设置为主键. IntegerField():一个整数: FloatFi ...

  8. Django基础(二):环境配置

    前戏 WEB框架简介 具体介绍Django之前,必须先介绍WEB框架等概念. web框架: 别人已经设定好的一个web网站模板,你学习它的规则,然后“填空”或“修改”成你自己需要的样子. 一般web框 ...

  9. Django基础篇--Models

    在Django中创建与数据库的链接并调用数据库的数据是很关键的步骤,那么怎么实现这个过程呢? 下面这篇文章简单梳理了一下创建Model层的过程和应用 模型-Models 首先需要理解什么是模型? 模型 ...

  10. Django 基础二(View和urls)

    上一篇博文已经成功安装了python环境和Django,并且新建了一个空的项目.接下来就可以正式开始进行Django下 的Web开发了.首先进入项目的主目录: cd ./DjangoLearn/hol ...

随机推荐

  1. java写出图形界面

    1. 做出简单的窗体 package javaGUI; import java.awt.BorderLayout; import java.awt.Color; import javax.swing. ...

  2. 解决Pycharm中matplotlib画图出错问题(AttributeError: module 'matplotlib' has no attribute 'verbose')

    最近在Linux中使用pycharm过程中使用matplotlib无法画图,总是提示错误 /usr/bin/python3. /home/leo/PycharmProjects/untitled1/E ...

  3. sp_rename sqlserver 表 列 索引 类型重命名

    --[语法] sp_rename [ @objname = ] 'object_name' , [ @newname = ] 'new_name' [ , [ @objtype = ] 'object ...

  4. mysql: instr 多个字段 like数据

    你是否一直在寻找比MySQL的LIKE语句更高效的方法的,下面我就为你介绍几种. SELECT * FROM `order_shop` where instr(uuid,  'b') > 0 g ...

  5. jsp用tags传递参数

    <computer:trangleTag sideA="12" sideB="12" sideC="12"/>表示以字符串传递s ...

  6. python中的excel操作

    一. Excel在python中的应用 存测试数据 有的时候大批量的数据,我们需要存到数据库中,在测试的时候才能用到.测试的时候就从数据库中读取出来.这点是非常重要的! 存测试结果 二. Excel中 ...

  7. 用lsmod看硬盘驱动决定是sata还是scsi盘

    sas盘 scsi盘 sata盘都是显示为sdx的所以无法区别唯一可以分别的是看看内核加载的驱动模块有啥 lsmod....mptsas      62545       7

  8. JS将数字转换成三位逗号分隔的样式

    function formatNum(num) { if(!/^(\+|-)?(\d+)(\.\d+)?$/.test(num)){alert("wrong!"); return ...

  9. 炫酷tab栏--第三方开源--NavigationTabStrip

    github下载地址:https://github.com/DevLight-Mobile-Agency/NavigationTabStrip 这个开源项目很强大,只是一个自定义的控件,只有一个类 / ...

  10. QQ发送位置(高德地图)

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout ...