ORM简介

  • MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
  • ORM是“对象-关系-映射”的简称。

#sql中的表                                                      

 #创建表:
CREATE TABLE employee(
id INT PRIMARY KEY auto_increment ,
name VARCHAR (20),
gender BIT default 1,
birthday DATA ,
department VARCHAR (20),
salary DECIMAL (8,2) unsigned,
); #sql中的表纪录 #添加一条表纪录:
INSERT employee (name,gender,birthday,salary,department)
VALUES ("alex",1,"1985-12-12",8000,"保洁部"); #查询一条表纪录:
SELECT * FROM employee WHERE age=24; #更新一条表纪录:
UPDATE employee SET birthday="1989-10-24" WHERE id=1; #删除一条表纪录:
DELETE FROM employee WHERE name="alex" #python的类
class Employee(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
gender=models.BooleanField()
birthday=models.DateField()
department=models.CharField(max_length=32)
salary=models.DecimalField(max_digits=8,decimal_places=2) #python的类对象
#添加一条表纪录:
emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保洁部")
emp.save()
#查询一条表纪录:
Employee.objects.filter(age=24)
#更新一条表纪录:
Employee.objects.filter(id=1).update(birthday="1989-10-24")
#删除一条表纪录:
Employee.objects.filter(name="alex").delete()

上图代码

单表操作

创建表

1  创建模型

注意:在创建表单之前,请先手动创建数据库.ORM不能创建数据库,需要我们自己创建.创建数据库时,记得要指定字符编码为utf8,否则添加表记录时,如果有汉字,可能会报错(原因是:默认的字符编码不是uft8,在进行decode时,类型不对)

在app01下,创建models.py文件,然后在此文件中写入下面的内容:

from django.db import models

# Create your models here.

class Book(models.Model):
id=models.AutoField(primary_key=True)
title=models.CharField(max_length=32)
state=models.BooleanField()
pub_date=models.DateField()
price=models.DecimalField(max_digits=8,decimal_places=2)
publish=models.CharField(max_length=32)

2 更多字段和参数

  每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

更多字段:

 '''

 <1> CharField
字符串字段, 用于较短的字符串.
CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数. <2> IntegerField
#用于保存一个整数. <3> FloatField
一个浮点数. 必须 提供两个参数: 参数 描述
max_digits 总位数(不包括小数点和符号)
decimal_places 小数位数
举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段: models.FloatField(..., max_digits=5, decimal_places=2)
要保存最大值一百万(小数点后保存10位)的话,你要这样定义: models.FloatField(..., max_digits=19, decimal_places=10)
admin 用一个文本框(<input type="text">)表示该字段保存的数据. <4> AutoField
一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
自定义一个主键:my_id=models.AutoField(primary_key=True)
如果你不指定主键的话,系统会自动添加一个主键字段到你的 model. <5> BooleanField
A true/false field. admin 用 checkbox 来表示此类字段. <6> TextField
一个容量很大的文本字段.
admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框). <7> EmailField
一个带有检查Email合法性的 CharField,不接受 maxlength 参数. <8> DateField
一个日期字段. 共有下列额外的可选参数:
Argument 描述
auto_now 当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.
auto_now_add 当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
(仅仅在admin中有意义...) <9> DateTimeField
一个日期时间字段. 类似 DateField 支持同样的附加选项. <10> ImageField
类似 FileField, 不过要校验上传对象是否是一个合法图片.#它有两个可选参数:height_field和width_field,
如果提供这两个参数,则图片将按提供的高度和宽度规格保存.
<11> FileField
一个文件上传字段.
要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting,
该格式将被上载文件的 date/time
替换(so that uploaded files don't fill up the given directory).
admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) . 注意:在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
(1)在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件.
(出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 作为该目录的公共 URL. 要确保该目录对
WEB服务器用户帐号是可写的.
(2) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
使用 MEDIA_ROOT 的哪个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT).
出于习惯你一定很想使用 Django 提供的 get_<#fieldname>_url 函数.举例来说,如果你的 ImageField
叫作 mug_shot, 你就可以在模板中以 {{ object.#get_mug_shot_url }} 这样的方式得到图像的绝对路径. <12> URLField
用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且
没有返回404响应).
admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框) <13> NullBooleanField
类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项
admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据. <14> SlugField
"Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们通常用于URLs
若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50. #在
以前的 Django 版本,没有任何办法改变50 这个长度.
这暗示了 db_index=True.
它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-#populate
the slug, via JavaScript,in the object's admin form: models.SlugField
(prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields. <13> XMLField
一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径. <14> FilePathField
可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
参数 描述
path 必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目.
Example: "/home/images".
match 可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名.
注意这个正则表达式只会应用到 base filename 而不是
路径全名. Example: "foo.*\.txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
这三个参数可以同时使用.
match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
FilePathField(path="/home/images", match="foo.*", recursive=True)
...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif <15> IPAddressField
一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
<16> CommaSeparatedIntegerField
用于存放逗号分隔的整数值. 类似 CharField, 必须要有maxlength参数. '''  

常用字段

更多参数:

(1)null

如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.

(1)blank

如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。 (2)default 字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。 (3)primary_key 如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。 (4)unique 如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的 (5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。

参数

3 settings配置

注意:要先注释掉Django默认的DATABASE

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'orm',      # 要连接的数据库,连接前需要创建好
'USER':'root',       # 连接数据库的用户名
'PASSWORD:'123',       # 连接数据库的密码
'HOST':'127.0.0.1', # 连接主机,默认本级
'PORT':3306     # 端口 默认3306
}
}

注意1:NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。然后,启动项目,会报错:no module named MySQLdb 。这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的__init__,在里面写入相应的配置

最后通过两条数据库迁移命令(在Terminal)即可在指定的数据库中创建表 :

python manage.py makemigrations
python manage.py migrate

注意2:确保配置文件中的INSTALLED_APPS中写入我们创建的app名称(如果没有,仅需添加一个"app01"即可):

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]

注意3:如果报错如下:django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

原因:MySQLclient目前只支持到python3.4,3.4以上的版本需要注释掉两行代码

MAC OSX:

在Finder中,前往文件夹输入报错的地址(项目所在的目录下面的venv里面):

/Users/nickguo/PycharmProjects/untitled/Luffycity/Django学习/ORM/venv/lib/python3.7/site-packages/django/db/backends/mysql/

打开base.py,找到下面的两句代码,注释掉:

 if version < (1, 3, 13):
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)

Windows系统:

通过查找路径C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql

注释掉两行代码即可.

注意4: 如果想打印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',
},
}
}  

添加表纪录

方式1

book_obj = Book(title="Python",state=True,pub_date="2019-04-21",price=95.46,publish="清华大学出版社")
book_obj.save()

方式2(推荐使用)


book_obj = Book.objects.create(title="python",state=True,pub_date="2018-02-19",price=97.43,publish="电子工业出版社")

查询表纪录

 
from django.shortcuts import render,HttpResponse

# Create your views here.

from app01.models import Book
# 注意,在添加表之前,我们创建db的时候,需要指定编码形式,否则可能会报错(我使用mac系统,创建时未指定编码,再插入边表记录时,含有汉字,则报encode错误) def index(request):
# 添加表记录的2种方式: # 方式一: # book_obj = Book(id="1",title="Python",state=True,pub_date="2019-04-21",price=95.46,publish="清华大学出版社")
# book_obj.save() # 方式二:
# book_obj = Book.objects.create(title="python",state=True,pub_date="2018-02-19",price=97.43,publish="电子工业出版社")
# book_obj = Book.objects.create(title="Linux"+str(i), state=True, pub_date="2017-05-29", price=96.63,
# publish="清华大学出版社") #------------------------单表查询API------------------------ #1.all()方法:返回的所以个queryset对象,由管理器调动 # book_list = Book.objects.all()
# print(book_list) #是一个新的数据类型,Queryset,相当于一个列表里,存放的是obj对象.[object1,object2,......]
# 支持序列操作
# for obj in book_list:
# print(obj.title,obj.price,obj.pub_date) # print(book_list[0].title) #2.first(),last():获取表中第一个记录,返回的是一个models对象,由queryset调用 # book = Book.objects.all().first()
# book1 = Book.objects.all().last()
# print(book) #Book object (1)
# print(book.title)
# print(book.price)
# print(book1.title)
# print(book1.price) # 3.filter():条件过滤(相当于where),由管理者调用,返回queryset对象,可以序列操作 # book_list = Book.objects.filter(title="python")
# print(book_list[0].title) #4.get():有且只有一个记录时才有意义,否则报错,返回:models对象 # book = Book.objects.get(price=56)
# print(book.title) #mysql实战 # 5.exclude():排除某项,由管理者调用,返回queryset # book_list = Book.objects.exclude(price=56)
# print(book_list) # 6.order_by:排序,queryset调用,返回queryset.默认升序 # book_list = Book.objects.all().order_by("-id") #加一个"-",就是降序
# book_list1 = Book.objects.all().order_by("price","id") #2个排序条件,当price相同时,按照id排序
# print(book_list)
# for obj in book_list:
# print(obj.id,obj.title) # 7.count():计数,调用者:queryset,返回值:int # ret = Book.objects.all().count()
# print(ret) # 8.exists():是否存在数据,调用者:queryset,返回值:布尔
# ret = Book.objects.all().exists()
# print(ret)
# if ret:
# print("有数据存在")
# else:
# print("没有数据")
#
#9.values():取表中所有记录的指定字段的值,调用者queryset,返回值:一个queryset的字典值列表
# ret = Book.objects.all().values("title","price")
# print(ret)
# print(ret[0].get("price")) # 10.values_list():取表中所有记录的指定字段的值,调用者queryset,返回值:一个queryset的元组
# ret = Book.objects.all().values_list("title", "price")
# print(ret)
# # print(ret[0].get("price")) # 11.distinct():去重复,一般配合values()或者values_list()使用,针对某个一个字段去重才有意义,但是对主键(如ID)使用distinct没有意义,因为一般ID是不可重复的
ret = Book.objects.all().values("price").distinct()
print(ret.count())
print(ret) return HttpResponse("OK")

基于双下划线的模糊查询  


from django.shortcuts import render,HttpResponse

# Create your views here.

from app01.models import Book

def index(request):

    # ---------------------------------------------------模糊查询api-----------------------------------------------------

    # 1.__gt=value:大于,返回queryset
# 价格大于50的书籍
# ret = Book.objects.filter(price__gt=20)
# for i in range(ret.count()):
# print("价格大于20的书籍有:",ret[i].title)
# # 价格大于50,小于100的书籍
# ret1 =Book.objects.filter(price__gt=50,price__lt=100)
# for i in range(ret.count()):
# print("价格介于50-100之间的书籍有:",ret1[i].title) # 注意,startwi和istartwith的区别是:startwith严格区分大小写,istartwith不区分大小写.以后遇见类似的,也是一样的 # 2.__startwith:以某个字符开头,返回queryset
# ret = Book.objects.filter(title__startswith="l")
# ret1 = Book.objects.filter(title__istartswith="l")
# print(ret)
# print(ret1)
#
# 3.__contains,__icontains:包含某个字符,在内的意思
# ret = Book.objects.filter(title__contains="2")
# print(ret) # 4.in:匹配一个或多个值,返回queryset
# ret =Book.objects.filter(price__in=[6.24,64.43,33.2,77.90,56.93])
# print(ret) # 5.__year:指定年查询,返回queryset
# ret =Book.objects.filter(pub_date__year=2008,pub_date__month=8)
# print(ret) return HttpResponse("OK")

单表修改和删除记录

删除记录:

# 1.delete():删除数据,调用者:queryset,models,返回一个元组
# ret = Book.objects.filter(price=33.22).delete() #queryset调用
# print(ret)
# ret = Book.objects.filter(price=50.22).first().delete() #models调用
# print(ret)

修改记录:

# 2.update():修改记录,调用者:queryset,models,返回一个int

    ret = Book.objects.filter(price=99.50).update(price=89.00,publish="机械工业出版社")
print(ret)

Django-6 Django ORM层的更多相关文章

  1. Django中的ORM

    Django中ORM的使用. 一.安装python连接mysql的模块:MySQL-python sudo pip install MySQL-python 安装完成后在python-shell中测试 ...

  2. django中的ORM介绍和字段及字段参数

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  3. Django中的ORM介绍,字段以及字段的参数。

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  4. Django之模型ORM

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  5. Django模型系统——ORM

    一.概论 1.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描 ...

  6. Django 中得ORM介绍和字段及字段参数

    ORM 介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说 ORM 是通过使用 ...

  7. Django的日常-模型层(2)

    目录 Django的日常-模型层(2) 几种常用的查询方式 聚合查询 分组查询 F和Q查询 查询优化相关 orm中常见字段 choices参数 orm的事务操作 Django的日常-模型层(2) 几种 ...

  8. Django的日常-模型层(1)

    目录 Django的日常-模型层(1) 模型层 django测试环境 ORM查询 Django的日常-模型层(1) 模型层 模型层其实就是我们应用名下的models.py文件,我们在里面写入想要创建的 ...

  9. Django框架之ORM常用字段

    一.ORM介绍 1.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过 ...

  10. Django中使用ORM

    一.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数 ...

随机推荐

  1. python:socket网络编程

    Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket, 又称为“套接字”. 模块 import socket 创建套接字 socket.socket( ...

  2. java~gradle构建公用包并上传到仓库~使用私有仓库的包

    在新的项目里使用仓库的包 上一讲中我们说了java~gradle构建公用包并上传到仓库,如何发布公用的非自启动类的包到私有仓库,而这一讲我们将学习如何使用这些包,就像我们使用spring框架里的功能包 ...

  3. 完美解决phpstudy安装后mysql无法启动(无需删除原数据库,无需更改任何配置,无需更改端口)直接共存

    PHPstudy与原Mysql兼容解决 一.前言 今天学习php,当然是要先安装好运行环境了,phpstyudy是一个运行php的集成环境, 一键安装对新手很友好,与时作为一个新手,便跟着教程安装了p ...

  4. 2018~第三届南宁市网络安全技术大赛~nnctf~write-up

    Web 1.超简单 分值:100 类型:WEB 已解决 题目:超简单的web题  http://gxnnctf.gxsosec.cn:12311/ 代码审计 <?php $white_list ...

  5. cocos creator主程入门教程(八)—— 代码结构

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇简单介绍下代码结构,清晰的代码结构更有利于团队对项目的理解和维护. 1.前面我们介绍了一系列基础功 ...

  6. 斑马打印机的安装调试,生成PDF

    1.  我使用的斑马打印机GK888T.有问题打客服,耐心等待.售后电话4006456456得到了解决. 2.  我遇到的问题是打印一张之后指示灯变为红灯,时好时坏.解决方案,长按指示键,待指示灯连续 ...

  7. git clone 指定分支

    使用Git下载指定分支命令为:git clone -b 分支名仓库地址 克隆asp.net core 2.1.6版本 git clone -b 2.1.6 https://github.com/asp ...

  8. while,for,if输入账号密码判断(还请各位大牛能够优化,本人刚学习一周)

    AccountNumber1 = [] password1 = [] flag = True while flag: num = 0 a = 1 print('-----------这是个欢迎界面-- ...

  9. Struts2笔记_值栈

    A.值栈概述 值栈(ValueStack),通俗的来说就是Struts2里面用来管理和存储数据的东西.struts2项目部署运行后,底层会创建一个action实例,同时也会在内存上划分一块区域,这个区 ...

  10. SAP MM A工厂下的PR可以转成B工厂下的PO?

    SAP MM A工厂下的PR可以转成B工厂下的PO? 答案是可能的,这也是SAP标准行为之一. 如下图采购申请单据, PR中的Plant是GENL.该PR 已经转成了PO,如上图. 看这个PO,工厂代 ...