Django基础(7)_ORM单表操作
ORM简介
对象关系映射 (Object Relational Mapping, 简称ORM).
简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

- MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
- ORM是“对象-关系-映射”的简称。(Object Relational Mapping,简称ORM)(将来会学一个sqlalchemy,是和他很像的,但是django的orm没有独立出来让别人去使用,虽然功能比sqlalchemy更强大,但是别人用不了)
- 类对象--->sql--->pymysql--->mysql服务端--->磁盘,orm其实就是将类对象的语法翻译成sql语句的一个引擎,明白orm是什么了,剩下的就是怎么使用orm,怎么来写类对象关系语句。
查看orm与原生sql的对应关系


ORM的优点:-不用写繁琐的SQL语句,用咱们熟悉的python代码,就能实现对数据的操作,提高开发效率;-可以平滑的操作,切换数据库。
ORM的缺点:-ORM代码转换为SQL语句时,需要花费一定的时间,执行效率会有所降低;-长期写ORM代码,导致写SQL语句能力,会有所减弱。
Django 使用mysql
手动创建数据库
注意:ORM无法操作到数据库级别,只能操作到数据表。
create datebase 数据库名称 charset utf8mb4;
在settings中配置数据库
1 DATABASES = { 2 'default': { 3 'ENGINE': 'django.db.backends.mysql', # 更改为mysql引擎 4 'NAME': "day49", # 数据库名称 5 "HOST": "127.0.0.1", # 数据库所在ip地址 6 'PORT': 3306, # 默认的端口 7 'USER': 'root', # 用户名 8 'PASSWORD': "123", # 密码 9 } 10 }
在settings.py的同级目录下的__init__.py设置
1 import pymysql 2 pymysql.install_as_MySQLdb()
在app下的models.py里写上模型类(单表)
1 class Book(models.Model): 2 # id会自动创建,并且是一个主键 3 title = models.CharField(max_length=32) 4 price = models.DecimalField(max_digits=5, decimal_places=2) # 最大值,只能是999.99 5 publish = models.CharField(max_length=64) 6 publish_date = models.DateField()
choices参数的介绍
sex_choice = ( (0, '女性'), (1, '男性'), ) class Author(models.Model): name = models.CharField( max_length=32) age = models.IntegerField() sex_choice = ( (0, '女性'), (1, '男性'), ) sex = models.IntegerField(choices=sex_choice,default=1) #choices关键字固定的 获取用户的性别 ret = models.Author.objects.get(id=1) ret.get_sex_display()
Django Model中字段(Field)的可选项和必选项
| 字段与选项(必选项为黄色标注) |
|
CharField() 字符字段
|
|
TextField() 文本字段
|
|
DateField() and DateTimeField() 日期与时间字段
|
|
EmailField() 邮件字段
|
|
IntegerField(), SlugField(), URLField(),BooleanField()
|
|
FileField(upload_to=None, max_length=100) - 文件字段
|
|
ImageField(upload_to=None, height_field=None, width_field=None, max_length=100,)
|
|
ForeignKey(to, on_delete, **options) - 单对多关系
|
|
ManyToManyField(to, **options) - 多对多关系
|
在命令行执行数据迁移的命令
1 python3 manage.py makemigrations # 把models.py的变更记录记录下来 2 python3 manage.py migrate # 把变更记录的操作同步到数据库中
关于同步指令的执行简单原理:
1 在执行 python manager.py magrations 时django 会在相应的 app 的migration文件夹下面生成 一个python脚本文件 2 在执行 python manager.py migrte 时 django才会生成数据库表,那么django是如何生成数据库表的呢, 3 django是根据 migration下面的脚本文件来生成数据表的 4 每个migration文件夹下面有多个脚本,那么django是如何知道该执行那个文件的呢,django有一张django-migrations表,表中记录了已经执行的脚本,那么表中没有的就是还没执行的脚本,则 执行migrate的时候就只执行表中没有记录的那些脚本。 5 有时在执行 migrate 的时候如果发现没有生成相应的表,可以看看在 django-migrations表中看看 脚本是否已经执行了, 6 可以删除 django-migrations 表中的记录 和 数据库中相应的 表 , 然后重新 执行
单表数据的增删改查
添加表记录
- 方式一: 新增 直接模型类实例化对象
1 def result(request): 2 # 增 方法一 3 book_obj = models.Book(title='三毛流浪记', price=122, publish='小树出版社', publish_date='1999-06-17') 4 book_obj.save() 5 return HttpResponse('ok')
- 方法二: 调用orm提供的API (推荐)
1 def result(request): 2 # 增 方法二 3 book_obj = models.Book.objects.create(title='红楼梦', price=12, publish='人民出版社', publish_date=datetime.datetime.now()) 4 print(book_obj) # Book object 5 return HttpResponse('ok')
- 批量添加
1 obj_list = [] 2 for i in range(10): 3 book_obj = models.Book( 4 title=f'少年阿宾{i}', 5 price=10 + i, 6 pub_date=f'2022-04-1{i}', 7 publish='32期红浪漫出版社' 8 9 ) 10 obj_list.append(book_obj) 11 12 models.Book.objects.bulk_create(obj_list) #bulk_create 批量添加
查询表记录
- 查询API
1 <1> all(): 查询所有结果,结果是queryset类型 2 3 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象,结果也是queryset类型 Book.objects.filter(title='linux',price=100) #里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,or关系的我们后面再学,直接在这里写是搞不定or的 4 5 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,不是queryset类型,是行记录对象,返回结果有且只有一个, 6 如果符合筛选条件的对象超过一个或者没有都会抛出错误。捕获异常try。 Book.objects.get(id=1) 7 8 <4> exclude(**kwargs): 排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操作昂,用这个exclude,返回值是queryset类型 Book.objects.exclude(id=6),返回id不等于6的所有的对象,或者在queryset基础上调用,Book.objects.all().exclude(id=6) 9 10 <5> order_by(*field): queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型 11 models.Book.objects.all().order_by('price','id') #直接写price,默认是按照price升序排列,按照字段降序排列,就写个负号就行了order_by('-price'),order_by('price','id')是多条件排序,按照price进行升序,price相同的数据,按照id进行升序 12 13 <6> reverse(): queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型 14 15 <7> count(): queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。 16 17 <8> first(): queryset类型的数据来调用,返回第一条记录 Book.objects.all()[0] = Book.objects.all().first(),得到的都是model对象,不是queryset 18 19 <9> last(): queryset类型的数据来调用,返回最后一条记录 20 21 <10> exists(): queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False 22 空的queryset类型数据也有布尔值True和False,但是一般不用它来判断数据库里面是不是有数据,如果有大量的数据,你用它来判断,那么就需要查询出所有的数据,效率太差了,用count或者exits 23 例:all_books = models.Book.objects.all().exists() #翻译成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是通过limit 1,取一条来看看是不是有数据 24 25 <11> values(*field): 用的比较多,queryset类型的数据来调用,返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 26 model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。 27 <12> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列,加个salt=True参数可以获取值列表 28 29 <13> distinct(): values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录
简单使用
1 def book_list(request): 2 # all 查询所有 返回QuerySet类型 3 books = models.Book.objects.all() # QuerySet类型 类似于list, 里面是一个个对象 4 # 类似与sql: select * from app01_book; 5 6 # filter 过滤 返回QuerySet类型 7 books = models.Book.objects.filter(pk=3) # QuerySet 类似于list, 满足条件的对象集 8 books = models.Book.objects.filter(price=200) 9 books = models.Book.objects.filter(publish='少林出版社', price=200) # 多个条件时,是使用and关系 10 11 # get 获取一个对象 12 books = models.Book.objects.get(pk=4) # 直接获取出对象 注意: 当查询条件不存在或者查询出结果有多个值时,会报错。 13 books = models.Book.objects.get(pk=18) # 直接获取出对象 14 books = models.Book.objects.get(price=200) # 直接获取出对象 15 16 # exclude # 排除满足条件的结果 返回QuerySet类型 17 18 # first()与last() 获取的是对象 19 books = models.Book.objects.filter(pk=4).first() 20 books = models.Book.objects.filter(pk=4).last() 21 22 books = models.Book.objects.exclude(publish='少林出版社', price=200) # not 排除满足条件的对象。剩下的取出来即可。 23 24 books = models.Book.objects.order_by("price") # 默认是升序 25 books = models.Book.objects.order_by("-price") # 默认是降序 26 27 # reverse 28 books = models.Book.objects.order_by("-price").reverse() # 默认是降序 29 30 # count 31 books = models.Book.objects.all().count() # 统计数量 32 33 # exists 34 books = models.Book.objects.filter(pk=18).exists() # 返回值为布尔值 35 36 # values # 返回QuerySet类型 里面类似于字典. 37 books = models.Book.objects.filter(price=200).values("title", "price") # QuerySet {'title': '易经', 'price': Decimal('200.00')} 38 39 # values_list # 返回QuerySet类型 里面类似于元组 40 books = models.Book.objects.filter(price=200).values_list("title", "price") # QuerySet ('易经', Decimal('200.00')), 41 42 # distinct() # 去重 43 books = models.Book.objects.filter(price=200).values_list("price").distinct() 44 return HttpResponse("查询成功!")
models.py的__str__的写法:
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) price = models.DecimalField(max_digits=8,decimal_places=2,) pub_date = models.DateTimeField() #必须存这种格式"2012-12-12" publish = models.CharField(max_length=32) def __str__(self): #后添加这个str方法,也不需要重新执行同步数据库的指令 return self.title #当我们打印这个类的对象的时候,显示title值
- 基于双下划线的模糊查询
1 def book_list(request): 2 books = models.Book.objects.filter(price__in=[100,200,300]) # 在... 里 3 books = models.Book.objects.filter(price__gt=100) # 大于 4 books = models.Book.objects.filter(price__gte=100) # 大于等于 5 books = models.Book.objects.filter(price__lt=100) # 小于 6 books = models.Book.objects.filter(price__range=[100, 200]) # 包含后面的数字 左闭右闭 7 books = models.Book.objects.filter(title__contains="法") # 包含... 8 books = models.Book.objects.filter(title__icontains="python") # 不区分大小写 9 books = models.Book.objects.filter(title__startswith="p") # 以...开头 (区分大小写) 10 books = models.Book.objects.filter(title__iendswith='P') # 以...结尾 (不区分大小写) 11 books = models.Book.objects.filter(pub_date__year=2018) # 通过年份过滤 12 return HttpResponse("查询成功!")
删除表记录
- 方式一 调用 QuerySet的delete方法
会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。
1 def del_book(request): 2 pk =request.GET.get('pk') 3 books = models.Book.object.filter(pk=pk).delete() 4 return HttpResponse('删除成功!')
- 方式二 obj.delete()
运行时立即删除对象而不返回任何值
1 def del_book(request): 2 pk = request.GET.get("pk") 3 books = models.Book.objects.filter(pk=pk).first() 4 books.delete() 5 return HttpResponse("删除成功!")
修改表记录
- 方式一: 调用QuerySet的 update()方法
1 def edit_book(request): 2 pk = request.GET.get("pk") 3 books = models.Book.objects.filter(pk=pk).update(price=280) 4 books = models.Book.objects.filter(pk=pk).update(price=290,publish='华山出版社') 5 return HttpResponse("编辑成功!")
update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数
- 方式二: obj更改属性值, 必须要save() 同步到数据库
1 def edit_book(request): 2 pk = request.GET.get("pk") 3 books = models.Book.objects.filter(pk=pk).first() 4 books.price = 189 5 books.save() 6 return HttpResponse("编辑成功!")
本文来自博客园,作者:长情不羁的五年,转载请注明原文链接:https://www.cnblogs.com/grlend/articles/14034642.html

浙公网安备 33010602011771号