目录

1.ORM

2.ORM单表增删改查

  13个必知必会的查询接口

  filter基于双下划线的模糊查询

3.ORM多表增删改查

ORM

什么是ORM?

ORM(object relational mapping) 对象关系映射,做数据库操作的

ORM中的对象关系映射

ORM的实际使用

1.首先,我们在django项目的app01/models.py中写入如下内容

class Book(models.Model):
# id 这行可写可不写,如果不写的话,系统也会自动添加上去
id = models.AutoField(primary_key=True) # id int primary key auto_increment,
title = models.CharField(max_length=32) # title varchar(32)
price = models.DecimalField(max_digits=5,decimal_places=2) #price decimal(5,2) 999.99
pub_date = models.DateField() # pub_date date
publish = models.CharField(max_length=32)

2.执行数据库同步指令,在项目根目录下面执行

python manage.py makemigraitons
python manage.py migrate

Tip:查看FIeld和mysql中的字段关系对比

C:\ProgramData\Anaconda3\Lib\site-packages\django\db\backends\mysql\base.py

具体内容大致如下

   _data_types = {
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)',
}

ORM单表的增删改查

配置连接数据库

1. 创建库:create database db01

2. 修改配置:在setting.py中更改如下内容

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db01',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':''
}
}

3.在项目主目录下面的init文件中写上如下内容

import pymysql
pymysql.install_as_MySQLdb()

注意:前提是需要安装pymysql : pip install pymysql

4.在pycharm中连接mysql,可以使用pycharm自带的sql可视化工具

在说增删改查之前,先介绍几个简单的查询接口

all()  '''获取表中所有数据,结果为queryset类型'''
ret = models.Book.objects.all() filter() '''获取部分数据,结果为queryset类型'''
ret = models.Book.objects.filter(title='西游记') get() '''获取单条数据,结果是model对象'''
ret = models.Book.objects.get(title='西游记')
'''关于get需要注意的点'''
# 1. get() 获取有且只能有一条
# 2.找不到会报错:Book matching query does not exist.
# 3.结果超过1条也报错: get() returned more than one Book -- it returned 3!

单表操作:增

'''方式1'''
obj = models.Book( # obj就是一个普通的类对象
title='西游记',
price=2.8,
# pub_date='2000-08-12', # 可以直接写固定时间,也可以写datetime当前时间
pub_date=datetime.datetime.now(), #时间日期类型
publish='人民出版社',
)
obj.save() # 注意:必须要写save选项
'''方式2'''
obj = models.Book.objects.create( # obj是当前创建的新的记录对象
title='红楼梦',
price=9.9,
# pub_date='2000-08-12', #这样的格式字符串
pub_date=datetime.datetime.now(), # 时间日期类型
publish='人民出版社',
) '''批量添加'''
obj_list = [] # 创建一个空列表,用来存放类对象
for i in range(1,4): # 创建4个类对象,每个对象都有4个字段
obj = models.Book(
title='水浒传' + str(i),
price=i,
pub_date=f'2000-08-1{i}',
publish='夕阳红出版社',
)
obj_list.append(obj) # 将类对象添加到列表中
models.Book.objects.bulk_create(obj_list) # 批量添加

单表操作:删

'''query类型数据和模型类对象都可以调用delete方法来进行删除'''
models.Book.objects.filter(title='西游记').delete()
models.Book.objects.get(id=3).delete()

单表操作:改

'''方式1'''
models.Book.objects.filter(id=4).update(
title='西游记',
price=4,
)
'''方式2'''
obj = models.Book.objects.get(id=6)
obj.price = 18 # 找到model对象,使用model对象.属性修改值
obj.save() obj.update() # 注意:模型类对象不能直接使用update方法

单表查询:查

13个必知必会的查询接口

前面已经提到了3个简单的查询接口,加上它们,一共有13个查询接口

all()  '''获取表中所有数据,结果为queryset类型'''
ret = models.Book.objects.all()

filter() '''获取部分数据,结果为queryset类型'''
ret = models.Book.objects.filter(title='西游记')
ret = models.Book.objects.filter(id=1,title='三国演义') # 多条件查询,条件之间是且的关系(and) get() '''获取单条数据,结果是model对象'''
ret = models.Book.objects.get(title='西游记')
'''关于get需要注意的点'''
# 1. get() 获取有且只能有一条
# 2.找不到会报错:Book matching query does not exist.
# 3.结果超过1条也报错: get() returned more than one Book -- it returned 3! exclude(**kwargs): '''排除的意思,它包含了与所给筛选条件不匹配的对象,返回值是queryset类型'''
models.Book.objects.exclude(id=6),# 返回id不等于6的所有的对象,
models.Book.objects.all().exclude(id=6) # 在queryset基础上也调用exclude                 
order_by(*field): '''queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型'''
models.Book.objects.all().order_by('price','id')
'''注意点'''
# 1.直接写price,默认是按照price升序排列,
# 2.按照字段降序排列,就写个负号就行了:order_by('-price'),
# 3.order_by('price','id')是多条件排序,按照price进行升序,price相同的数据,按照id进行升序


reverse() '''queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型,在排序基础上才能使用'''
models.Book.objects.all().order_by('id').reverse() # 注意:要在order_by 基础上使用

count():'''queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量'''
models.Book.objects.all().count()

first(): '''queryset类型的数据来调用,返回第一条记录'''
Book.objects.all()[0] = Book.objects.all().first() # 得到的都是model对象,不是queryset

last(): '''queryset类型的数据来调用,返回最后一条记录'''
# 注意:在ORM中不能使用复数索引
ret = models.Book.objects.all()[-1] # 报错,不支持负数索引:Negative indexing is not supported. exists(): '''queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False'''

values(*field): '''用的比较多,queryset类型的数据来调用,返回一个QuerySet'''
ret = models.Book.objects.values('title','price')
# 获取所有记录的某些字段数据,结果为querset类型,里面的元素是字典类型数据,属性名称为键,对应记录的字段数据为值
'''还可以通过queryset类型数据来调用'''
ret = models.Book.objects.all().values('title','price')


values_list(*field): '''它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列'''
ret = models.Book.objects.all().values_list('title','price')
ret = models.Book.objects.values_list('title','price')

distinct(): '''values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复记录'''
ret = models.Book.objects.all().values_list('price').distinct()

filter基于双下划线的模糊查询

# 1.按日期查询
ret = models.Book.objects.filter(pub_date__year='', pub_date__month='',pub_date__day='') # 2.以..开头/结尾
ret = models.Book.objects.filter(title__startswith='少妇') # 以..开头(区分大小写)
ret = models.Book.objects.filter(title__istartswith='py') # 以..开头(不区分大小写)
ret = models.Book.objects.filter(title__endswith='') # 以..结尾(区分大小写) # 3.包含
ret = models.Book.objects.filter(title_icontains='python') # title值中包含python的(区分大小写)
ret = models.Book.objects.filter(title__icontains='python') # title值中包含python的(不区分大小写) # 4.数字等于.../数字在某个范围内
ret = models.Book.objects.filter(price__in=[3,4]) # 等于3或者等于4 -- 3 or4
ret = models.Book.objects.filter(price__range=[1,3]) # 在1-3之间 between 1 and 3 # 5.年份写纯数字和字符串数字都可以
ret = models.Book.objects.filter(pub_date__year=2018)
ret = models.Book.objects.filter(pub_date__year='') # 6.大于/大于等于/小于/小于等于
ret = models.Book.objects.filter(price__gt=3) # 价格大于3的
ret = models.Book.objects.filter(price__gte=3) # 价格大于等于3的
ret = models.Book.objects.filter(price__lt=3) # 价格小于3的
ret = models.Book.objects.filter(price__lte=3) # 价格小于等于3的

ORM多表关系的增删改查

ORM多表关系的创建

from django.db import models

# 作者表
class Author(models.Model): # 比较常用的信息放到这个表里面
name=models.CharField( max_length=32)
age=models.IntegerField() #int
# 与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以
ad = models.OneToOneField(to="AuthorDetail", to_field='id', on_delete=models.CASCADE) # 作者详细信息表
class AuthorDetail(models.Model): # 不常用的放到这个表里面
birthday=models.DateField()
telephone=models.CharField(max_length=11)
addr=models.CharField(max_length=64) # 出版社表
class Publish(models.Model):
name=models.CharField( max_length=32)
city=models.CharField( max_length=32) # 书籍表
class Book(models.Model):
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
# publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)
publish=models.ForeignKey(to="Publish") #默认级联删除,默认关联的是另外一张表的id字段
authors=models.ManyToManyField(to='Author',) #自动创建第三张表,id author_id book_id,不会作为本表的字段出现

创建字段的一些参数讲解

# 1.null
'''如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.''' # 2.blank
'''
如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
''' # 3.default
'''
字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用,如果你的字段没有设置可以为空,那么将来如果我们后添加一个字段,这个字段就要给一个default值
''' # 4.primary_key
'''
如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。
''' # 5.unique
'''如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的''' # 6.choices
'''由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。''' # 7.db_index
'''如果db_index=True 则代表着为此字段设置数据库索引''' # DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。 # 8.auto_now_add
'''配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库''' # 9.auto_now
'''配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间'''

Tip:关于choices属性额外的补充

sex = models.IntegerField(choices=((1, '男性'), (2, '女性')))
'''注意点'''
# 1.数据库里面存的是1或者2
# 2.通过model模型类对象.get_属性名称_display()可以获取到数字对应的文本内容

Tip:关于auto_now_add和auto_now属性额外的补充

class t1(models.Model):
d1 = models.DateTimeField(auto_now_add=True,null=True) #自动添加创建记录的时间
d2 = models.DateTimeField(auto_now=True,null=True) #自动添加创建记录的时间,更新记录是也能自动更新为最新时间
'''注意点'''
# 1.auto_now 自动更新时间只有在save更新时才生效,update不生效
# 2.所以如果要做更新时间的处理,那么最好手动获取当前时间并修改

多表操作:增

# 一对一
# 1.用create增
models.AuthorDetail.objects.create(
birthday='2018-01-01',
telephone='',
addr='北京'
)
ad_obj = models.AuthorDetail.objects.get(id=1) # 创建一对一的关联model对象
models.Author.objects.create(
name='张三',
age=38,
# ad=ad_obj, # 方法一:写关联对象
ad_id=2, # 方法二:直接写关联id值
)
# 2.用类对象去增
ad_obj = models.AuthorDetail.objects.get(id=4)
obj= models.Author(
name='杨浩',
age=47,
ad=ad_obj, # 方法一
# ad_id=3, # 方法二
)
obj.save() # 一对多
'''出版社和书是一对多的关系;一个出版社可以出版多本书'''
# 一对多,在多的一方写关联语句
models.Book.objects.create(
title='西游记',
publishDate='2018-08-08',
price=22,
# publishs=models.Publish.objects.get(id=1), # 方法一
publishs_id=1, # 方法二
) # 多对多
'''书和作者是多对多的关系;一本书可以有多个作者,一个作者也可以写很多本书'''
obj = models.Book.objects.filter(id=1).first()
# 方法一:通过get(id=?)获取对象
a1 = models.Author.objects.get(id=1)
a2 = models.Author.objects.get(id=2)
obj.authors.add(a1,a2)
# 方法二:add中直接写id
obj.authors.add(1,2)
# 方法三:id写入列表中,用*号打散
obj.authors.add(*[1,2])

多表操作:删

# 一对一和一对多删除
'''一对一和一对多 ,基本和单表一样(级联删除)'''
models.Author.objects.get(id=1).delete() models.AuthorDetail.objects.get(id=2).delete()
models.Book.objects.get(id=1).delete() # 多对多删除
ret = models.Book.objects.get(id=2)
ret.authors.clear() # 清空该书籍对应的第三张表中的记录(全部删除)
ret.authors.remove(3,4) #指定删除该书和哪些作者的关系 (指定删除)

day52:django:ORM单表/多表操作的更多相关文章

  1. Django ORM - 001 - 外键表查询主表信息

    开始用Django做web开发,我想大家都会遇到同样的问题,那就是如何高效快速的查询需要的数据,MVC都很简单,但是ORM折腾起来就有些费时间,我准备好好研究下Django ORM,所以会有一个系列的 ...

  2. django ORM单表操作

    1.ORM介绍 ORM是“对象-关系-映射”的简称 映射关系: mysql---------Python 表名----------类名 字段----------属性 表记录--------实例化对象 ...

  3. Django ORM单表查询必会13条

    必知必会13条 操作下面的操作之前,我们实现创建好了数据表,这里主要演示下面的操作,不再细讲创建准备过程 <1> all(): 查询所有结果 <2> filter(**kwar ...

  4. Django orm self 自关联表

    自关联模型 自关联模型就是表中的某一列,关联了这个表的另外一列.最典型的自关联模型就是地区表.省市县都在一张表里面.省的pid为null,市的pid为省的pid,县的pid为市的ID. class A ...

  5. django框架基础-ORM单表操作-长期维护

    ###############    单表操作-添加数据    ################ import os if __name__ == '__main__': os.environ.set ...

  6. Django框架05 /orm单表操作

    Django框架05 /orm单表操作 目录 Django框架05 /orm单表操作 1. orm使用流程 2. orm字段 3. orm参数 4. orm单表简单增/删/改 5. orm单表查询 5 ...

  7. day59——orm单表操作

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

  8. Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段

    单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...

  9. python 之 Django框架(orm单表查询、orm多表查询、聚合查询、分组查询、F查询、 Q查询、事务、Django ORM执行原生SQL)

    12.329 orm单表查询 import os if __name__ == '__main__': # 指定当前py脚本需要加载的Django项目配置信息 os.environ.setdefaul ...

随机推荐

  1. asp.net core 应用docke部署到centos7

    前言 前期准备 win10 (不要安装hyper-V) VMware-Workstation-Pro/15.0 Xshell6 (非必需) VS2019 以上环境请自行安装 都是默认安装没什么可说的 ...

  2. Salesforce学习笔记之吐槽

    迄今感到的几个不方便 1. SOQL里没有SELECT * ,只好根据参考手册和用vs code的一个插件Schema Explorer来辅助生成SELECT语句. 2. SOQL不支持注释,Deve ...

  3. JAVA 读取excel文件成List<Entity>

    package com.fsinfo.common.utils; import com.fsinfo.modules.enterprise.entity.EnterpriseRecordEntity; ...

  4. 微信access token过期

    两台服务器使用同一个微信账号(同一个app id) 时,当其中一台服务器向微信请求access token时,会造成另一台服务器的access token过期

  5. 记一次 gltf 模型的绘制性能提升:从ppt到dove,丝滑感受

    转换思路 同样一个模型,分别取如下转换思路: 原始模型fbxgltf 原始模型objgltf 但是我在打开中间格式fbx和obj时,发现这两者虽然顶点数量一致,三角形数量一致,但是使用 Windows ...

  6. ImportError: No module named git

    问题:ImportError: No module named git 解决:yum install GitPython

  7. Shell编程—用户输入

    1命令行参数 1.1读取参数 bash shell会将一些称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的所有参数.这也包括shell所执行的脚本名称.位置参数 ...

  8. 前端 的一些css的写法

    攒一下小技巧 1.select 默认提示但是不显示在选择列表中 <option selected="selected" disabled="disabled&quo ...

  9. Redis秒杀实战-微信抢红包-秒杀库存,附案例源码(Jmeter压测)

    导读 前二天我写了一篇,Redis高级项目实战(点我直达),SpringBoot整合Redis附源码(点我直达),今天我们来做一下Redis秒杀系统的设计.当然啦,Redis基础知识还不过关的,先去加 ...

  10. Java程序员博客系统推荐!我调研了100来个 Java 开源博客系统,发现这 5 个最好用!

    大家好!我是 Guide 哥,Java 后端开发.一个会一点前端,喜欢烹饪的自由少年. 最近想倒腾一下博客,看了很多现成的比较成熟的开源博客系统,自己也简单从下面几个维度总结对比了一下: star数量 ...