ORM 是个啥?

在python中的一个默认的编写规范是一切皆对象,这样做使得代码简洁,结构清晰,便于维护和重用代码,同时极大的提升开发效率。

同样在操作数据库时,一般我们用SQL语句来实现操作,但是放在Python中是一串冗长的字符串,不利于调试和修改,更不符合上面提到的规范。

所以,有大佬就提出ORM来替代原生的SQL语句,说白了ORM 就是要给缩写,代表着 对象-关系-映射

简写 全称 中文
O Object 对象
R Relational 关系
M Mapping 映射

有了ORM,我们来看它与实际的数据库是怎么联系起来的:

数据库 ORM
数据库的表(table ) 类(class)
记录,行数据(record) 对象(object)
字段(field) 对象的属性(attribute)

ORM相对原始SQL的优劣势

  • 优势

    • 专注业务逻辑开发,提升开发效率
    • 易于更新维护,重用代码
    • 会自动完成比如数据消毒,预处理,事务等功能
    • 不用编写复杂的SQL语句
  • 劣势
    • 牺牲执行效率,增加查询时间
    • 无法操作底层数据库,无法实现某些复杂操作
    • 遗忘SQL语句编写

怎么选择原生SQL和ORM

  • 对于复杂的SQL语句或数据库层面,推荐使用原始SQL
  • 对于要处理复杂的业务逻辑,加快开发,推荐使用ORM
  • ORM 相对 原始SQL在一般的业务中,损耗其实并不高,可以忽略不计

开发前准备

新建项目

配置数据库

配置模型

字段类型和参数

常用字段

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Baimoc
# @Email   : baimoc@163.com
# @Time    : 2020/7/24 9:45from django.db import modelsclass Field(models.Model):# 自增字段Auto = models.AutoField()# 自增字段,最大值可拓展到更大BigAuto = models.BigAutoField()# 二进制数据Binary = models.BinaryField()# 布尔型Boolean = models.BooleanField()NullBoolean = models.NullBooleanField() # 允许为空的布尔型# 整型PositiveSmallInterger = models.PositiveSmallIntegerField()  # 长度为 5字节正整数SmallIntegerField = models.SmallIntegerField()   # 长度为 6字节整数PositiveIntegerField = models.PositiveIntegerField()   # 长度为 10字节正整数IntegerField = models.IntegerField()   # 长度为 11字节正整数BigIntegerField = models.BigIntegerField()   # 长度为 20字节正整数# 字符串类型Char = models.CharField()  # varcharText = models.TextField()  # longtext# 时间日期类型Date = models.DateField()  # 年月日DateTime = models.DateTimeField()  # 年月日时分秒Duration = models.DurationField()  # int,Python timedelta实现# 浮点型Float = models.FloatField()Decimal = models.DecimalField()  # 需要指定整数或小数有多少位# 高级字段Email = models.EmailField()Image = models.ImageField()File = models.FileField()FilePath = models.FilePathField()URL = models.URLField()UUID = models.UUIDField()

关系型字段

一对一(OneToOneField)

多对一(ForeignKey)

多对多(ManyToManyField)

class A(models.Model):one2one = models.OneToOneField(Field)class B(models.Model):one2one = models.ForeignKey(A)class C(models.Model):one2one = models.ManyToManyField(B)

字段参数

  • 所有字段都具有的参数

    • db_column:修改字段名
    • primary_key:主键
    • verbose_name:字段别名,备注
    • unique:值是否唯一
    • null:数据空中的值,是否允许为空
    • blank:前端表单提交时,是否可以为空,一般null=True,blank=True
    • db_index:是否建立字段索引
    • help_text:显示帮助
    • editable:后台是否可以编辑
  • 个别字段才有的参数
    • CharField

      • max_length:最大长度值
    • DateField
      • unique_for_date:该日期的值是否唯一
      • unique_for_month:该月份的值是否唯一
      • auto_now=True:更新数据时间
      • auto_now_add=True:插入数据时间
    • DecimalField
      • max_digits:多少位数
      • decimal_places:多少位小数,例子(max_digits=4,decimal_places=2),可以存储11.11,32.55
  • 关系型字段的参数
    • related_name:用于外键关联的反向查询,父表查子表
    • on_delete:当外键被删除时,要进行什么操作

自关联

例子:省市县的存储

class AddressInfo(models.Model):address = models.CharField(max_length=200, null=True, blank=True, verbose_name="地址")pid = models.ForeignKey('self', null=True, blank=True, verbose_name='自关联', on_delete=models.CASCADE)  # 写法一# pid = models.ForeignKey('AddressInfo', null=True, blank=True, verbose_name='自关联')  # 写法二def __str__(self):return self.address

元数据

class AddressInfo(models.Model):address = models.CharField(max_length=200, null=True, blank=True, verbose_name="地址")pid = models.ForeignKey('self', null=True, blank=True, verbose_name='自关联', on_delete=models.CASCADE)  # 写法一# pid = models.ForeignKey('AddressInfo', null=True, blank=True, verbose_name='自关联')  # 写法二note = models.CharField(max_length=200, null=True, blank=True, verbose_name="说明")def __str__(self):return self.addressclass Meta:# 定义数据表名db_table='address'# 按照哪个字段排序# ordering=('pid',)# 表别名verbose_name='地址信息'# 表别名复数,用于英文显示verbose_name_plural=verbose_name# 设置基类,不生成数据表,作为其他表的基类# abstract=False# 设置表权限# permissions=(('定义好的权限', '权限说明'),)# 是否按照Django既定的规则来管理模型类# managed=False# 联合唯一键# unique_together=('address', 'note')  # 另一种写法 ((),())# 定义模型类属于哪个应用# app_label='myapp1

实例

建表

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Baimoc
# @Email   : baimoc@163.com
# @Time    : 2020/7/24 9:45from django.db import modelsclass Teacher(models.Model):"""讲师信息表"""nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name="昵称")introduction = models.TextField(default="这位同学很懒,木有签名", verbose_name="简洁")fans = models.PositiveIntegerField(default="0", verbose_name="粉丝数")created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:verbose_name = "讲师信息表"verbose_name_plural = verbose_namedef __str__(self):return self.nicknameclass Course(models.Model):"""课程信息表"""title = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="课程名")# 老师和课程为多对一关系,使用 ForeignKey 来实现teacher = models.ForeignKey(Teacher, null=True, on_delete=models.CASCADE, verbose_name="课程讲师")type = models.CharField(choices=((1, "实战课"), (2, "免费课"), (0, "其他")), max_length=1, default=0, verbose_name="课程类")price = models.PositiveSmallIntegerField(verbose_name="价格")volume = models.BigIntegerField(verbose_name="销量")online = models.DateField(verbose_name="上线时间")created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:verbose_name = "课程信息表"verbose_name_plural = verbose_namedef __str__(self):# 返回type的描述信息return f"{self.get_type_display(), self.title}"class Student(models.Model):"""学生信息表"""nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name="昵称")# 课程与学生是多对多关系course = models.ManyToManyField(Course, verbose_name="课程")age = models.PositiveSmallIntegerField(verbose_name="年龄")gender = models.CharField(choices=((1, "男"), (2, "女"), (0, "保密")), max_length=1, default=0, verbose_name="性别")study_time = models.PositiveIntegerField(default="0", verbose_name="学习时长(h)")created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:verbose_name = "学生信息表"verbose_name_plural = verbose_namedef __str__(self):return self.nicknameclass TeacherAssisant(models.Model):"""助教信息表"""nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name="昵称")teacher = models.OneToOneField(Teacher, null=True, on_delete=models.SET_NULL, verbose_name="讲师")hobby = models.CharField(max_length=100, null=True, blank=True, verbose_name="爱好")created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:verbose_name = "助教信息表"db_table = "courses_assistant"verbose_name_plural = verbose_namedef __str__(self):return self.nickname

更改数据库表

删除模型类的步骤

  • 删除表模型
  • 删除项目中migraions文件夹下模型类生成的对应文件
  • 删除数据库migraions表中的生成记录
  • 删除数据表

导入数据

1.命令行添加

数据库中的数据表

2. 脚本添加
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Baimoc
# @Email   : baimoc@163.com
# @Time    : 2020/7/24 15:29
# @File    : orm_dataimport os
import sys
import random
import django
from datetime import dateproject_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_path)  # 将项目路径添加到系统搜寻路径当中
os.environ['DJANGO_SETTINGS_MODULE'] = 'orm_baimoc.settings'  # 设置项目的配置文件
django.setup()from ormbaimoc.models import Teacher, Course, Student, TeacherAssisantdef import_data():"""使用 Django ORM 导入数据"""# 讲师数据Teacher.objects.create(nickname="Jack", introduction="Python 工程师", fans=123)Teacher.objects.create(nickname="Allen", introduction="Java 工程师", fans=321)Teacher.objects.create(nickname="Henry", introduction="Golang 工程师", fans=888)# 课程数据Course.objects.bulk_create([Course(title=f"Python 系列教程{i}",teacher=Teacher.objects.get(nickname="Jack"),type=random.choice((0, 1, 2)),price=random.randint(200,300),volume=random.randint(100, 10000),online=date(2018, 10, 1))for i in range(1, 5)])Course.objects.bulk_create([Course(title=f"Java 系列教程{i}",teacher=Teacher.objects.get(nickname="Allen"),type=random.choice((0, 1, 2)),price=random.randint(200,300),volume=random.randint(100, 10000),online=date(2018, 6, 6))for i in range(1, 4)])Course.objects.bulk_create([Course(title=f"Golang 系列教程{i}",teacher=Teacher.objects.get(nickname="Henry"),type=random.choice((0, 1, 2)),price=random.randint(200,300),volume=random.randint(100, 10000),online=date(2020, 11, 1))for i in range(1, 3)])# 学生数据Student.objects.update_or_create(nickname="赵同学", defaults={"age":random.randint(18, 58),"gender":random.choice((0, 1, 2)),"study_time":random.randint(9, 999),})Student.objects.update_or_create(nickname="吴同学", defaults={"age": random.randint(18, 58),"gender": random.choice((0, 1, 2)),"study_time": random.randint(9, 999),})Student.objects.update_or_create(nickname="郑同学", defaults={"age":random.randint(18, 58),"gender":random.choice((0, 1, 2)),"study_time":random.randint(9, 999),})Student.objects.update_or_create(nickname="王同学", defaults={"age": random.randint(18, 58),"gender": random.choice((0, 1, 2)),"study_time": random.randint(9, 999),})# 正向添加# 销量大于等于 1000 的课程Student.objects.get(nickname="赵同学").course.add(*Course.objects.filter(volume__gte=1000))# 销量大于 5000 的课程Student.objects.get(nickname="王同学").course.add(*Course.objects.filter(volume__gt=5000))# 反向添加# 学习实践大于等于 500 小时的同学Course.objects.get(title="Python 系列教程1").student_set.add(*Student.objects.filter(study_time__gte=500))# 学习实践小于等于 500 小时的同学Course.objects.get(title="Python 系列教程1").student_set.add(*Student.objects.filter(study_time__lte=500))# 助教数据 get_or_createTeacherAssisant.objects.get_or_create(nickname="助教1",defaults={"hobby":"慕课网学习", "teacher":Teacher.objects.get(nickname="Jack")})TeacherAssisant.objects.get_or_create(nickname="助教2",defaults={"hobby": "看电影", "teacher": Teacher.objects.get(nickname="Allen")})TeacherAssisant.objects.get_or_create(nickname="助教3",defaults={"hobby": "读书", "teacher": Teacher.objects.get(nickname="Henry")})return Trueif __name__ == '__main__':if import_data():print("导入数据成功")# 其他导入数据方法
# fixtures Django serialization 保存
# 数据库层面的导入数据

Model API

基本查询

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Baimoc
# @Email   : baimoc@163.com
# @Time    : 2020/7/26 18:39
# @File    : viewfrom django.shortcuts import render
from django.views.generic import View
from django.http import JsonResponse
from .models import AddressInfo, Teacher, Course,Student,TeacherAssisantclass IndexView(View):"""主页"""def get(self, request):# 查询全部teachers = Teacher.objects.all()print(teachers)# 获取一个值# 只能返回一条结果,多条会报错teachers2 = Teacher.objects.get(nickname='Jack')print(teachers2, type(teachers2))# 查询符合条件的多个值# 返回QuerySet,可以是多条结果teachers3 = Teacher.objects.filter(fans__gte=500)for teacher in teachers3:print(f"讲师姓名:{teacher.nickname} --> 粉丝数:{teacher.fans}")# 字段数据匹配teacher4 = Teacher.objects.filter(fans__in=[888])print(teacher4)# 结果切片print(Teacher.objects.all()[:2])# 排序teacher6 = Teacher.objects.all().order_by('.fans')for t in teacher6:print(t.fans)# 链式查询teacher7 = Teacher.objects.filter(fans__gte=100).order_by('nickname')print(teacher7)# 查询原生SQLprint(Teacher.objects.filter(fans__gte=100).order_by('nickname').query)return render(request, "address.html")

返回新 QuerySet API

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Baimoc
# @Email   : baimoc@163.com
# @Time    : 2020/7/26 18:39
# @File    : view
from datetime import datefrom django.db.models import Sum, Avg, Max, Min
from django.shortcuts import render
from django.views.generic import View
from django.http import JsonResponse
from .models import AddressInfo, Teacher, Course,Student,TeacherAssisant, GroupConcatclass IndexView(View):"""主页"""def get(self, request):# 查询全部teachers = Teacher.objects.all()print(teachers)# 获取一个值# 只能返回一条结果,多条会报错teachers2 = Teacher.objects.get(nickname='Jack')print(teachers2, type(teachers2))# 查询符合条件的多个值# 返回QuerySet,可以是多条结果teachers3 = Teacher.objects.filter(fans__gte=500)for teacher in teachers3:print(f"讲师姓名:{teacher.nickname} --> 粉丝数:{teacher.fans}")# 字段数据匹配teacher4 = Teacher.objects.filter(fans__in=[888])print(teacher4)# 结果切片print(Teacher.objects.all()[:2])# 排序teacher6 = Teacher.objects.all().order_by('.fans')for t in teacher6:print(t.fans)# 链式查询teacher7 = Teacher.objects.filter(fans__gte=100).order_by('nickname')print(teacher7)# 查询原生SQLprint(Teacher.objects.filter(fans__gte=100).order_by('nickname').query)# 返回新 Query API# 排除print(Student.objects.all().exclude(nickname="王同学"))# 排序print(Student.objects.all().exclude(nickname="王同学").reverse())# 修改返回结果的字段名,将nickname改为namestudents = Student.objects.all().extra(select={"name":"nickname"})for student in students:print(student.name)# 获取字典或元组形式的 QuerySetprint(TeacherAssisant.objects.values('nickname', 'hobby'))# < QuerySet[{'nickname': '助教1', 'hobby': '慕课网学习'}, {'nickname': '助教2', 'hobby': '看电影'}, {'nickname': '助教3', 'hobby': '读书'}] >print(TeacherAssisant.objects.values_list('nickname', 'hobby'))# <QuerySet [('助教1', '慕课网学习'), ('助教2', '看电影'), ('助教3', '读书')]>print(TeacherAssisant.objects.values_list('nickname', flat=True))# <QuerySet ['助教2', '助教3', '助教1']># 根据日期获取查询集print(Course.objects.dates('created_at', 'day', order='DESC'))# <QuerySet [datetime.date(2020, 7, 26)]>print(Course.objects.datetimes('created_at', 'second', order='DESC'))# <QuerySet [datetime.datetime(2020, 7, 26, 9, 25, 21, tzinfo=<UTC>)]># 并集:union、交集:inersection、差集:differencep_240 = Course.objects.filter(price__gte=240)p_260 = Course.objects.filter(price__lte=260)print(p_240.union(p_260))# 引擎不支持会报错# print(p_240.inersection(p_260))# print(p_240.difference(p_260))# 一对多、多对一查询优化:select_related# 一对多、多对多查询优化:prefetch_relatedcourses = Course.objects.all()for c in courses:print(f"{c.title} -- {c.teacher.nickname} -- {c.teacher.fans}")# (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None# (0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None# (0.000) SELECT `ormbaimoc_course`.`title`, `ormbaimoc_course`.`teacher_id`, `ormbaimoc_course`.`type`, `ormbaimoc_course`.`price`, `ormbaimoc_course`.`volume`, `ormbaimoc_course`.`online`, `ormbaimoc_course`.`created_at`, `ormbaimoc_course`.`updated_at` FROM `ormbaimoc_course`; args=()# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Henry' LIMIT 21; args=('Henry',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Henry' LIMIT 21; args=('Henry',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Allen' LIMIT 21; args=('Allen',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Allen' LIMIT 21; args=('Allen',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Allen' LIMIT 21; args=('Allen',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Jack' LIMIT 21; args=('Jack',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Jack' LIMIT 21; args=('Jack',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Jack' LIMIT 21; args=('Jack',)# (0.000) SELECT `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_teacher` WHERE `ormbaimoc_teacher`.`nickname` = 'Jack' LIMIT 21; args=('Jack',)courses = Course.objects.all().select_related('teacher')for c in courses:print(f"{c.title} -- {c.teacher.nickname} -- {c.teacher.fans}")# (0.016) (SELECT `ormbaimoc_course`.`title`, `ormbaimoc_course`.`teacher_id`, `ormbaimoc_course`.`type`, `ormbaimoc_course`.`price`, `ormbaimoc_course`.`volume`, `ormbaimoc_course`.`online`, `ormbaimoc_course`.`created_at`, `ormbaimoc_course`.`updated_at` FROM `ormbaimoc_course` WHERE `ormbaimoc_course`.`price` >= 240) UNION (SELECT `ormbaimoc_course`.`title`, `ormbaimoc_course`.`teacher_id`, `ormbaimoc_course`.`type`, `ormbaimoc_course`.`price`, `ormbaimoc_course`.`volume`, `ormbaimoc_course`.`online`, `ormbaimoc_course`.`created_at`, `ormbaimoc_course`.`updated_at` FROM `ormbaimoc_course` WHERE `ormbaimoc_course`.`price` <= 260) LIMIT 21; args=(240, 260)# (0.000) SELECT `ormbaimoc_course`.`title`, `ormbaimoc_course`.`teacher_id`, `ormbaimoc_course`.`type`, `ormbaimoc_course`.`price`, `ormbaimoc_course`.`volume`, `ormbaimoc_course`.`online`, `ormbaimoc_course`.`created_at`, `ormbaimoc_course`.`updated_at`, `ormbaimoc_teacher`.`nickname`, `ormbaimoc_teacher`.`introduction`, `ormbaimoc_teacher`.`fans`, `ormbaimoc_teacher`.`created_at`, `ormbaimoc_teacher`.`updated_at` FROM `ormbaimoc_course` LEFT OUTER JOIN `ormbaimoc_teacher` ON (`ormbaimoc_course`.`teacher_id` = `ormbaimoc_teacher`.`nickname`); args=()students = Student.objects.filter(age__lt=30).prefetch_related("course")for s in students:print(s.course.all())# (0.000) SELECT @@SQL_AUTO_IS_NULL; args=None# (0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None# (0.000) SELECT `ormbaimoc_student`.`nickname`, `ormbaimoc_student`.`age`, `ormbaimoc_student`.`gender`, `ormbaimoc_student`.`study_time`, `ormbaimoc_student`.`created_at`, `ormbaimoc_student`.`updated_at` FROM `ormbaimoc_student` WHERE `ormbaimoc_student`.`age` < 30 ORDER BY `ormbaimoc_student`.`age` ASC; args=(30,)# 反向查询:父表查询子表print(Teacher.objects.get(nickname="Jack").course_set.all())# print(Teacher.objects.get(nickname="Jack").teacher.all())# annotate(): 使用聚合计数,求和,平均等print(Course.objects.values('teacher').annotate(vol=Sum('volume')))print(Course.objects.values('teacher').annotate(vol=Avg('volume')))print(Course.objects.values('teacher').annotate(vol=Max('volume')))print(Course.objects.values('teacher').annotate(vol=Min('volume')))# raw(),执行原始SQL"""不返回 Query API """# 获取对象 ---------------------------------# get()# get_or_create()# first()print(Course.objects.first())# last()print(Course.objects.last())# latest(), 注意需要设置 get_latest_by = 'created_at'print(Course.objects.latest())# earliest()print(Course.objects.earliest())# in_bulk(), 批量插入数据print(Course.objects.in_bulk(['Golang 系列教程1', 'Python 系列教程4']))# 更新对象 ---------------------------------# update()Course.objects.filter(title="Golang 系列教程1").update(price=6666)# update_or_create()Course.objects.filter(title="Java 系列教程5").update_or_create(title="Java 系列教程5", price=888, volume=55, online=date(2018, 6, 6))# 删除对象 ----------------------------------Course.objects.filter(title='Java 系列教程5').delete()# 其他操作 exists(),count(), aggregate(),判断是否存在,统计个数,聚合print(Course.objects.filter(title='test').exists())print(Course.objects.filter(title='Golang 系列教程1').exists())print(Course.objects.count())print(Course.objects.aggregate(Max('price'), Min('price'), Avg('price'), Sum('volume')))

参考

http://www.ruanyifeng.com/blog/2019/02/orm-tutorial.html

https://www.imooc.com/video/18466

Django 使用 ORM 操作数据库详解相关推荐

  1. php phonegap,phonegap操作数据库详解

    这次给大家带来phonegap操作数据库详解,phonegap操作数据库的注意事项有哪些,下面就是实战案例,一起来看一下. 实例如下: Database Example document.addEve ...

  2. 【云开发】小程序端操作数据库详解

    文章目录 云数据库 云数据库简介 手动操作数据库 小程序端操作数据库

  3. Java操作数据库详解

    目录 JDBC简介 JDBC的使用 数据库连接方式 案例程序 Statement和PreparedStatement的区别 JDBC简介 JDBC(Java Data Base Connectivit ...

  4. Jmeter操作数据库详解

    https://www.bilibili.com/video/BV1st411Y7QW?p=91&spm_id_from=pageDriver 进一步详细信息参考: 软件测试工程师必备之Jme ...

  5. Django工程-ORM模型数据库操作详解(六)

    Django工程-ORM模型数据库操作 下面以用户和图书表模型进行ORM的基本操作使用 ORM模型介绍 1.增加 通过模型类.objects.create()保存. >>> User ...

  6. 067:【Django数据库】ORM查询条件详解-range

    [Django数据库]ORM查询条件详解-range range: 判断某个 field 的值是否在给定的区间中.示例代码如下: # views.py文件内容:from datetime import ...

  7. Django从理论到实战(part28)--ORM常用Field详解

    学习笔记,仅供参考 参考自:Django打造大型企业官网–Huang Y: ORM常用Field详解 AutoField 映射到数据库中是int类型,可以有自动增长的特性.一般不需要使用这个类型,如果 ...

  8. [Python从零到壹] 八.数据库之MySQL和Sqlite基础知识及操作万字详解

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  9. pandas读写MySQL数据库详解及实战

    pandas读写MySQL数据库详解及实战 SQLAlchemy是Python中最有名的ORM工具. 关于ORM: 全称Object Relational Mapping(对象关系映射). 特点是操纵 ...

最新文章

  1. 服务器中使用Com组建处理Excel 常见问题
  2. 全面屏适配方案,终极版,华为隐藏导航栏解决方案
  3. Django中的auth模块
  4. linux下imwbr1进程,Linux服务器中木马wnTKYg
  5. nga能查服务器状态吗,NGAA
  6. Python模块:日志输出—logging模块
  7. django mysql 一对多_请教,django中 如何向带有外键(一对多和多对多)数据库中批量插入数据?...
  8. 分别用雅可比(Jacobi)迭代法和高斯—塞德尔(Gauss—Seidel)迭代法求解线性方程组(转载)
  9. 归并排序(包含逆序数对的个数51Nod1019)
  10. Web测试中性能测试基础
  11. ie11不兼容java_解决ie11不兼容的多个方法
  12. 听力测试英语软件初中,初中生英语听力软件
  13. 初学树莓派——(六)树莓派安装OpenCV及USB摄像头配置
  14. TMS320C64x DSP L1 L2 Cache架构(1)——C64x Cache Architecture
  15. win7 摄像头驱动软件找不到,只有sys文件
  16. 阵道计算机,太古神王电脑版
  17. Gartner发布2022年云平台服务技术成熟度曲线,iPaaS、低代码将达到成熟期
  18. Flutter画中画自定义画中画
  19. VGG论文原文重点提炼解析
  20. ZeroBrane Studio远程调试Cocos2d-x的Lua脚本

热门文章

  1. 惠通科技冲刺深交所:年营收5亿 严旭明与张建纲为实控人
  2. uV胶点胶机器人_UV胶点胶机选择那种针头点胶?
  3. 电线直径对照表_电缆直径对照表
  4. make matcaffe:出现的问题及解决办法
  5. python画出小猪佩奇
  6. 新闻稿标题怎么写才能引发共鸣?
  7. linux中文件系统相关命令,linux磁盘、文件系统相关命令介绍
  8. 从回收站删除的文件如何恢复?独门诀窍大放送
  9. pages文稿进去显示服务器,pages文稿服务器地址
  10. 刺激战场国际服外挂太多?不存在的,你还可以这样操作