ORM的单表操作

MTV框架包含一个重要的部分就是ORM————对象关系映射(Object Relational Mapping),它实现了数据模型与数据库的解耦,即数据模型的设计。利用它我们不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动。
这里需要注意的是,ORM只能对表进行操作,也可以对表下面的记录进行操作,但是ORM不能对数据库进行操作,不能创建与删除数据库。也就是说,数据库必须提前创建好,接着ORM在数据库中进行表的操作。
为了方便大家理解,我们先将SQL中建表语句ORM中建表的类进行对比,便于大家对后面知识点的理解:

单表操作

创建表的过程

注意数据库需要利用MySQL创建,这里我们创建一个名为whw的数据库:create database whw;
接着新建一个Django项目,whw_dj_ORM,在这这个项目中新建一个应用book:python manage.py startapp book
接着,)确保配置文件中的INSTALLED_APPS中写入我们常见的book应用的名称。在全局的settings.py的INSTALLED_APPS中加入book:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#前面是既有的,这个book是新加的
'book',
]
然后在book应用中的models.py文件中加入下面建表的类的代码(如果没有名字必须命名为models):
from django.db import models
class Book(models.Model):
#AutoField为自增对象,括号里面的是限定条件
id = models.AutoField(primary_key=True)
#CharField为一个字符串,括号里面表示它的最大长度
title = models.CharField(max_length=32)
state = models.BooleanField()
#DateField是存日期的
pub_date =models.DateField()
#DecimalField是一个浮点型:max_digits为最大的位数,但是有两位是小数——111111.11
price = models.DecimalField(max_digits=8,decimal_places=2)
publish = models.CharField(max_length=32) def __str__(self):
return self.title
python文件中的类写好了,接下来我们就要进行配置让我们的程序与数据库连通了。
首先,想要将模型转换为mysql数据库中的表,需要在全局的settings中配置,需要注意的是创建数据库的时候这些参数都有设置的,而且下面的参数是连接本机的数据库,如果要连接远程数据库就需要远程数据库的ip 端口等信息了。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',#引擎,选mysql
'NAME':'whw',      # 要连接的数据库,连接前需要创建好
'USER':'root',       # 连接数据库的用户名
'PASSWORD':'123',       # 连接数据库的密码
'HOST':'127.0.0.1', # 连接主机,默认本本机
'PORT':3306     # 端口 默认3306
}
}
如果此时直接启动项目会报错:no module named MySQLdb 。这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到全局项目名文件下的init.py,在里面写入:
import pymysql
pymysql.install_as_MySQLdb()
还需要注意的一点是,如果我们用的是django2.0版本,然后python用的是3.4以上的版本,需要进行如下的操作:
A:在python与django的安装路径找到:C:\Users\dell\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\db\backends\mysql
B:将里面的base.py文件中的
if version < (1, 3, 3):
raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
这句话注释掉!!!
最后通过两条数据库迁移命令即可在指定的数据库中创建表(在Terminal中敲这两行代码就行了):
python manage.py makemigrations
python manage.py migrate
然后我们就可以在数据库中看到新建的表book_book(还有其他的表)了。
如果想打印orm转换过程中的sql,需要在settings中进行如下配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
如果程序没有报错,我们的程序就成功的连接到了MySQL数据库!接下来就是对数据库的操作了。

数据的增删改查

添加表记录

方式一:直接实例化一个类对象————注意object有很多方法,create是用来创建表的
book_obj=models.Book.objects.create(title='Python葵花宝典',state=True,price=100,publish='苹果出版社',pub_date='2015-12-13')
print(book_obj.title)
方式二:
book_obj=Book(title="python葵花宝典",state=True,price=100,publish="苹果出版社",pub_date="2012-12-12")

book_obj.save()

查询表记录——查询的API。

这里我们一定要知道每个方法的返回值是什么,以及每个方法是由谁来调用的!
(1)all()——将查询出来的查询出来的所有对象放在列表中。models.Book.objects来调用,返回的是QuerySet类型的对象
book_list = models.Book.objects.all()
print(book_list) for i in book_list:
print(i.title,i.price) print(book_list[0].pub_date)
(2)firstlast——返回值不是QuerySet对象,而是model对象,等价于book_list[0]或book_list[-1]。调用者是QuerySet对象。
book_first = models.Book.objects.first()
print(book_first)
(3)filter——功能跟SQL语句中的where一样,用来“过滤数据”。调用者objects,返回值是QuerySet对象。
book_list2 = models.Book.objects.filter(price=100)
print(book_list2)
可以带多个过滤条件:
book_list2_more = models.Book.objects.filter(price=100,title='西游记')
print(book_list2_more)
(4)get——很像filter,但是,get方法有且只有一个查询结果是才有意义;如果有多个查询结果会报错!返回值是一个model对象,利用objects调用!
book_get = models.Book.objects.get(title='西游记')
print(book_get)
(5)exclude——排除。得到的是个QuerySet对象,由objects调用。
book_exclude = models.Book.objects.exclude(title='西游记')
print(book_exclude)
(6)order_by——排序。###得到的是QuerySet对象,由objects调用。
(6-1)默认升序:
book_order_by_asc = models.Book.objects.order_by('title')
print('升序:',book_order_by_asc)
(6-2)降序排序:
book_order_by_desc = models.Book.objects.order_by('-title')
print('降序:',book_order_by_desc)
(6-3)也可以利用两个字段排序:——第一个字段相等的时候再用第二个字段排序:
book_order_by1 = models.Book.objects.order_by('title','price')
print('两个字段排序:',book_order_by1)
(7)reverse——反转。可以在order_by的基础上加上reverse:
book_reverse = models.Book.objects.order_by('title').reverse()
print('排序反转:',book_reverse)
(8)count——计数。返回int类型的数据,调用者是QuerySet。
count = models.Book.objects.all().count()
print('数据的总数:',(count,type(count)))
(9)exists——检测是否存在记录。如果想要判断表中有无数据,不加exists则表示取出来所有的值了,没必要取所有的值,这样效率不高;加上exists相当于利用limit限制只取出来一条数据去判断有没有记录。
ret = models.Book.objects.all().exists()
if ret:
print('OK!有数据!')
(10)values(*field)——得到的是一个QuerySet对象,由QuerySet对象调用。如果我们想对查询出来的QuerySet对象进行进一步的筛选可以用它。比如说查询所有书籍的名称:
book_titles = models.Book.objects.all().values('title')
print('所有书籍的名称:',book_titles)
由于values很重要,这里给出它的原理:
temp = []
for obj in models.Book.objects.all()
temp.append(
'title':obj.title,
)
return temp
大家注意了:返回的是一个列表,但是,列表中放的不是一个个的对象了,而是一个个的title作为key的字典!因此,对于得出的结果我们可以利用操作字典的方法去操作它:
book_title_1_title = book_titles[1].get('title')
print('第二个书籍的名字:',book_title_1_title)
(11)values_list(*field)——与value方法一样,调用者与返回值均是QuerySet对象。但是,value_list的结果是列表里面嵌套元组:
book_values_list = models.Book.objects.all().values_list('title')
print(book_values_list)
(12)distinct——去重。
price_distinct = models.Book.objects.all().values('price').distinct()
print('price去重:',price_distinct)

带双下划线的模糊查询

注意要用filter过滤。
(1)大于:__gt
gt_100 = models.Book.objects.filter(price__gt=100)
print('价格大于100的:',gt_100)
(2)小于:__lt
lt_10000 = models.Book.objects.filter(price__lt=10000)
print('价格小于10000的:',lt_10000)
(3)价格包含[100,200,300]这几个的:__in
price_in = models.Book.objects.filter(price__in=[100,200,300])
print('价格包含:',price_in)
(4)title以“西”字开头的数据:__startswith
title_starts_xi = models.Book.objects.filter(title__startswith='西')
print('title以西字开头:',title_starts_xi)
(5)包含——__contains
title_contains = models.Book.objects.filter(title__contains='p')
print('title包含p的:',title_contains)
(6)忽略大小写的包含——__icontains
title_icontains = models.Book.objects.filter(title__icontains='p')
print('title包含p或者P的:',title_icontains)
(7)在一个范围之内:__range
price_range = models.Book.objects.filter(price__range=[100,10000])
print('价格在一个范围之内:',price_range)
(8)关于日期的模糊查询。注意只有date类型的字段才有__year__month等。过滤一下出版日期是2014年的数据:
pub_date_2014 = models.Book.objects.filter(pub_date__year=2014)
print('2014出版的数据:',pub_date_2014)

删除记录与修改记录

删除——delete
方法一:QuerySet方法调用delete方法:models.Book.objects.filter(price=100).delete()
方法二:用model对象:models.Book.objects.filter(price=100).first().delete()
修改——update
注意必须使用QuerySet对象调用:models.Book.objects.filter(title='西游记').update(title='西游降魔篇')

ORM的单表操作的更多相关文章

  1. Django中模型层中ORM的单表操作

    ORM概念: MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员 ...

  2. ORM 简介 单表操作

    cls超 Django基础五之django模型层(一)单表操作 本节目录 一 ORM简介 二 单表操作 三xxx 一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型 ...

  3. Django开发:(3.1)ORM:单表操作

    MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需 ...

  4. ORM之单表操作

    ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...

  5. web框架开发-Django模型层(1)之ORM简介和单表操作

    ORM简介 不需要使用pymysql的硬编码方式,在py文件中写sql语句,提供更简便,更上层的接口,数据迁移方便(有转换的引擎,方便迁移到不同的数据库平台)…(很多优点),缺点,因为多了转换环节,效 ...

  6. 单表操作ORM

    博客园 首页 新随笔 联系 管理 订阅 随笔- 0  文章- 339  评论- 29  Django基础五之django模型层(一)单表操作   本节目录 一 ORM简介 二 单表操作 三 章节作业 ...

  7. orm单表操作

    二.orm简介 ORM:object relation mapping (ORM是“对象-关系-映射”的简称) MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦, ...

  8. day59——orm单表操作

    day59 orm单表操作 对象关系映射(object relational mapping) orm语句 -- sql -- 调用pymysql客户端发送sql -- mysql服务端接收到指令并执 ...

  9. 模型层之ORM、数据库和单表操作

    一.ORM简介 ORM是“对象-关系-映射”的简称,一般指持久化数据和实体对象的映射 1.1 什么是“持久化” 持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中( ...

随机推荐

  1. hdu2328 Corporate Identity 扩展KMP

    Beside other services, ACM helps companies to clearly state their “corporate identity”, which includ ...

  2. NSNull floatValue intValue 找不到指定方法解决方式

    最近遇到一个问题:         因为后台人员对于接口数据没有做空值处理.导致client接收到的有些数据为空(NSNull),而针对此类数据恰好client的存储结构为int和float类型.类型 ...

  3. laya的那些坑

    游戏运行在chrome里面 听不见声音 游戏运行在chrome里面  听不见声音:其它浏览器可以听见声音开发者模式提示如下: The AudioContext was not allowed to s ...

  4. 两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同

    思路:利用&用算加右移的方法来提取二进制中的每一位数,然后进行比较,查看是否相同. #include<stdio.h> #include<stdlib.h> int m ...

  5. HI3518E平台ISP调试环境搭建

    海思的SDK提供了ISP调试的相关工具,降低了IPC的ISP调试的难度.初次搭建ISP调试环境,记录一下. SDK版本:Hi3518_MPP_V1.0.A.0 硬件平台:HI3518E_OV9732 ...

  6. 路由器外接硬盘做nas可行吗?

    话说把家里的newifi mini升级到最新版后,又外接了个移动硬盘做nas,第一部就打算吧手机的视频移过去.一试才发现这速度慢的不行.只有几百kb 所以说,用是能用,单着速度也太慢了 再就是貌似硬盘 ...

  7. MySQL 数据类型对比:char 与 varchar;varchar 与 text;datetime 与 timestamp;blob 与 text;

    char 与 varchar char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉.所以 char 类型存储的字符串末尾不能有空格,varchar 不限于此. char(n) 固 ...

  8. zookeeper 相关

    zookeeper是什么: zk 是 一个注册机,提供分布式锁. zookerper可以做什么: 利用上面这两个特性.zookeeper 可以 为分布式提供 集群 的 一些管理 比如 高可用,名字服务 ...

  9. Iris分类以及数组reshape想到的

    最近在研究Iris花的逻辑回归分类中看到了如下的代码: from sklearn.linear_model import LogisticRegression X = iris["data& ...

  10. Jenkins进阶-用户权限管理(10)

    在版本发布的由于大家的分工不同,所以想通过控制用户的账号达到权限管理,对每个角色进行权限控制,最初通过"项目矩阵授权策略"的策略对每个项目进行单一的权限控制,当时也满足了效果,随着 ...