Django的学习进阶(三)————ORM

django框架是将数据库信息进行了封装,采起了html

类——>数据表java

对象——>记录python

属性——>字段git

经过这种一一对应方式完成了orm的基本映射
官方文档:https://docs.djangoproject.com/en/2.2/

1、表单
models中每个继承于models.Model的类就是一张数据表
如:class AddressInfo就是一张关于地址的数据表
官方文档:https://docs.djangoproject.com/en/2.2/topics/db/models/

2、字段
文档地址:https://docs.djangoproject.com/en/2.2/ref/models/fields/
(1)字段设计
1.自增加字段(default=int)程序员

# 自增加字段 Auto = models.AutoField() # 默认为整型 BigAuto = models.BigAutoField() # 比Auto大

 

2.二进制的数据sql

# 二进制字段 Binary = models.BinaryField() # 二进制字段

 

3.boolean类型shell

# Boolean类型 Boolean = models.BooleanField() # 不为空 NullBoolean = models.NullBooleanField() # 为空

 

4.整型数据库

# 整型 PositiveSmallInteger = models.PositiveSmallIntegerField() # 能存取五个字节的大小 SmallInteger = models.SmallIntegerField() # 能存取六个字节的大小 能够是正整数也能够是负整数 PositiveInteger = models.PositiveIntegerField() # 10个字节大小的正整数 Integer = models.IntegerField() # 11个字节大小的正整数 BigInteger = models.BigIntegerField() # 20个字节大小的整形


5.字符型express

# 字符串类型 Char = models.CharField() # varchar Text = models.TextField() # longtext

 

6.时间类型django

# 时间日期类型 Date = models.DateField() # 年月日 DateTime = models.DateTimeField() # 年月日时分秒 Duration = models.DurationField() # 一段时间 int 底层用Python timedelta实现

 

7.浮点型

# 浮点型 Float = models.FloatField() # 浮点型 Decimal = models.DecimalField() # 须要指定整数多少位 小数多少位

 

8.其余字段

# 其余字段 Email = models.EmailField() # 邮箱 Image = models.ImageField() # 图片 File = models.FileField() # 文件 FilePath = models.FilePathField() # 文件路径 URL = models.URLField() # 网址 UUID = models.UUIDField() # 通用惟一识别码 GenericIpAddress = models.GenericIPAddressField() # ip地址 ipv4的地址 或者是ipv6的地址


(2)字段参数设计
1.通用参数

# db_column="" 指定在数据库中的参数 # primary_key=True 设置主键 True # verbose_name="" 设置别名 # unique=True 设置字段是否惟一 # null=True, blank=True, db_index=True null是表中的字段是否为空 blank是表单提交的数据要和null保持一致 不然就会出现错误 同时给字段创建索引 # help_text="" 创建帮助文档 # editable=False 使用户不能够修改
# max_length = 20 指定最大长度

 

2.个别参数具备的字段

# date类型: unique_for_date=True 设置日期必须惟一 还有月和年 # date类型: auto_now_add=True 增长记录时的时间 插入数据的时间 # date类型: auto_now=True 更新当前记录的时间 更新数据的时间 # Decimal类型: max_digits=4 总共多少位, decimal_places=2 小数的位数

 

3.关系型字段

# related_name='' 外键查询的信息 # on_delete: 当外键不在的时候进行什么操做 做为关系型字段的必须参数(默认顺序是外键表to和on_delete) # on_delete的六种模式 """ models.CASCADE: 删除级联 A表记录被删除B表记录也会被删除 默认 要设定null=True blank=True models.PROTECT: 删除时 会报PROTECT ERROR异常 models.SET: 传一个SET值或者回调函数值 models.SET_NULL: 删除置空 父表记录被删除子表记录设置成NULL 同时须要指定null=True blank=True models.SET_DEFAULT: 当父表字段被删除的时候咱们给子表字段设置一个默认值 用default参数指定值 models.DO_NOTHING: 当父表被删除子表什么也不作 """

 
(3)关联关系
关联关系分为三种:一对一,一对多,多对多
1.基类

class Teacher(models.Model): # 教师类 objects = models.Manager() class Meta: verbose_name = "讲师信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname

 

2.一对一

其中的to和on_delete是必须参数,且要设计null和blank都要为空

class TeacherAssistant(models.Model): # 助教类 objects = models.Manager() # 外键关联 # 一对一 助教和教师 teacher = models.OneToOneField(to=Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="讲师")

 

2.一对多
其中的to和on_delete是必须参数,且要设计null和blank都为空

class Course(models.Model): objects = models.Manager() # 外键关联 # 一对多 一个讲师对应多个课程 # 其中to和on_delete是必须参数 teacher = models.ForeignKey(to=Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='课程讲师')

 

3.多对多
其中的to是必须参数

class Student(models.Model): # 学生类 objects = models.Manager() # 外键关联 # 多对多 学生和课程 course = models.ManyToManyField(to=Course, verbose_name='课程信息')

 

(4)自关联
利用自关联的特性构建一个相似于省市县的方法
关联的时候可使用‘self’或者是模型名

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

 
3、元数据
文档地址:https://docs.djangoproject.com/en/2.2/ref/models/options/
设置数据库的表名等信息,对数据进行一个操做等
一些meta中的实例,官网有更多的字段介绍和更加详细的字段信息

class AddressInfo(models.Model): class Meta: ordering = ['pid'] # 指定按照什么 字段进行排序:-pid 是降序 没有-表示升序 添加字段的顺序表示排序的前后结果 verbose_name = '省市县' # 设置成一个直观的名字在admin中 verbose_name_plural = verbose_name # 设置成复数 abstract = True # 不生成数据表 做为其余类的基类 permissions = [('定义好的权限', '给权限的说明'), ] # 二元的列表或者是元组 managed = False # 是否按照Django既定的模型类管理 好比是否建立数据表 unique_together = [] # 联合惟一键, 可使用一元列表:只使用一组字段做为约束条件 二元列表:[[], []] db_table = 'address' # 修改数据库的表名 app_label = 'app_name' # 定义模型类属于哪个应用, 在app没有添加到setting的配置环境中 db_tablespace = 'db_tablespace_name' # 定义数据库表空间的名字

 

4、Django的数据表
(1)models生成流程
1.数据表的代码

class 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="粉丝数") create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) objects = models.Manager() class Meta: verbose_name = "讲师信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class Course(models.Model): title = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="课程名") course_type = models.CharField(choices=((0, '其余'), (1, "实战课"), (2, "免费课程")), max_length=1, default=0, verbose_name="课程类型") price = models.PositiveSmallIntegerField(verbose_name="价格") volume = models.BigIntegerField(verbose_name="销量") online = models.DateField(verbose_name="上线时间") create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) # 系统本身添加 update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) # 系统本身添加 objects = models.Manager() # 外键关联 # 一对多 一个讲师对应多个课程 teacher = models.ForeignKey(to=Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='课程讲师') class Meta: verbose_name = "课程信息表" verbose_name_plural = verbose_name def __str__(self): # _get_FIELD_display能够展现Filed的类型 return f"{self._get_FIELD_display(self.course_type)}-{self.title}" class Student(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, 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)") create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) objects = models.Manager() # 外键关联 # 多对多 学生和课程 course = models.ManyToManyField(to=Course, verbose_name='课程信息') class Meta: verbose_name = "学生信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class TeacherAssistant(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='昵称', ) hobby = models.CharField(max_length=30, null=True, blank=True, verbose_name='爱好', ) create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) objects = models.Manager() # 外键关联 # 一对一 teacher = models.OneToOneField(to=Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="讲师") class Meta: verbose_name = "讲师助手信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname
View Code

 

2.在对应的应用的migration中生成对应的migrations文件
经过使用指令:【python manage.py makemigrations】完成数据的迁移,在对应的APP下面的migrations里面生成迁移数据日志


3.在django_migrations下面的生成记录

经过指令:【python manage.py migrate】完成数据的建表信息,将migrations里面的数据日志转成数据库语言存入数据库中

 

4.在数据库中生成的数据表

 
5.删除数据表
所以再删除的时候按照上面的四步就能够删除一个models类

(2)导入数据
1.Django-shell
使用【python manage.py shell】进入到命令行,导入对应的类建立对象完成数据的保存,【from [appname].models import [模板类]】

 

2.脚本
按照sys、os——>配置环境文件——>导入Django——>导入数据表.严格按照这个顺序导入数据信息,不然就会报错
其中settings前面的是项目的名字
参考blog:https://blog.csdn.net/qq_40999403/article/details/80694545

# -*- coding:utf-8 -*- # __author__ == pzq # @email: 1427655779@qq.co import os import sys import random from datetime import date # 将django项目根目录加入环境变量 parent_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(parent_path) # 引入django配置文件 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "film.settings") # 启动django import django django.setup() from index.models import Student, Course, TeacherAssistant, Teacher def import_data(): # 使用Django ORM导入数据 # 讲师数据 create() Teacher.objects.create(nickname='Jack', introduction="Python工程师", fans=random.randint(500, 1000)) Teacher.objects.create(nickname="Jerry", introduction="Java工程师", fans=random.randint(200, 800)) Teacher.objects.create(nickname="Peter", introduction="PHP工程师", fans=random.randint(400, 700)) Teacher.objects.create(nickname="Kate", introduction="C++工程师", fans=random.randint(100, 400)) # 课程数据 bulk_create() 批量导入数据 # 外键的链接经过对象 Course.objects.bulk_create([Course(title=f"python入门课程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(1000, 10000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Jack")) for i in range(1, 4)]) Course.objects.bulk_create([Course(title=f"Java入门课程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(2000, 9000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Jerry")) for i in range(1, 5)]) Course.objects.bulk_create([Course(title=f"PHP进阶课程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(1000, 4000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Peter")) for i in range(1, 3)]) Course.objects.bulk_create([Course(title=f"C++高阶课程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(1000, 2000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Kate")) for i in range(1, 4)]) # 学生数据 # update_or_create() 先经过nickname如今数据库中找寻这个数据 若是存在就update若是不存在就create # 把主键或者惟一键放在外面 把其余参数放在里面 Student.objects.update_or_create(nickname="A同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) Student.objects.update_or_create(nickname="B同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) Student.objects.update_or_create(nickname="C同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) Student.objects.update_or_create(nickname="D同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) # 接下来添加外键字段 # 正向添加 pk能够代替主键查找 子表关联到父表 # 销量大于等于1000的课程 Student.objects.get(nickname="A同窗").course.add(*Course.objects.filter(volume__gte=1000)) # 销量大于5000的课程 Student.objects.get(nickname="B同窗").course.add(*Course.objects.filter(volume__gt=5000)) # 反向添加 经过课程关联到学生 # 学习时间大于等于500小时的同窗 Course.objects.get(title="python入门课程1").student_set.add(*Student.objects.filter(study_time__gte=1500)) # 学习时间小于等于500小时的同窗 Course.objects.get(title="python入门课程2").student_set.add(*Student.objects.filter(study_time__lte=1500)) # 助教数据 get_or_create() 先经过nickname的关键字或者是主键进行查找 若是有就获取没有就建立 TeacherAssistant.objects.update_or_create(nickname="助教1", defaults={"hobby": "慕课网学习", "teacher": Teacher.objects.get(nickname="Jack")}) TeacherAssistant.objects.update_or_create(nickname="助教2", defaults={"hobby": "中国Mooc学习", "teacher": Teacher.objects.get(nickname="Jerry")}) TeacherAssistant.objects.update_or_create(nickname="助教3", defaults={"hobby": "程序员客栈", "teacher": Teacher.objects.get(nickname="Peter")}) TeacherAssistant.objects.update_or_create(nickname="助教4", defaults={"hobby": "牛客网", "teacher": Teacher.objects.get(nickname="Kate")}) return True if __name__ == '__main__': try: if import_data(): print("数据导入成功!") except Exception as AddError: print(AddError)
View Code

 

3.fixtures  Django serialization ——>  model  保存到数据库
使用指令【python manage.py dumpdata > film.json】输出数据库文件


使用指令【python manage.py loaddata film.json】输入数据到数据库

 

4.经过数据库层面来实现
导入SQL文件等

(3)导出数据
1.mange.py dumpdata > [文件名]
2.使用pycharm或者是Navicat等数据工具来导出
3.使用数据库层面:MySQL  dumpdata来实现

5、models API
queryset文档:https://docs.djangoproject.com/en/2.2/ref/models/querysets/
(1)查询介绍

def start(request): """ int类型的操做函数: gte:大于等于 exact:等于 gt:大于 in:在某某以内 isnull:是否为空 lt:小于 lte:小于等于 range:在什么范围内 字符型更多:其中i是忽略大小写敏感 """ # 1.查询 检索 过滤 # 返回的是对象 teacher = Teacher.objects.filter(fans__gte=500) # 是个query集 给字段匹配数据的时候必定要用双下划线 # 其中pk是主键 在这里就是nickname的关键字 t1 = Teacher.objects.get(pk="Jack") # get只能返回一条结果 全部采起主键或者是惟一键 t2 = Teacher.objects.all() # 查询全部数据 返回全部数据的对象集 # # 2.字段匹配大小写敏感 t3 = Teacher.objects.filter(pk__icontains="A") # 有不少能够去查看一下官网 # # 3.结果切片 排序 链式查询 # 切片 t3_1 = Teacher.objects.all().order_by('-fans')[1:] # 排序 t4 = Teacher.objects.all().order_by('-fans') # -表明降序 按照老师的粉丝数进行排序 t4_1 = Teacher.objects.all().order_by('fans') # 默认升序 # # 链式查询 t5 = Teacher.objects.filter(fans__gte=500).order_by('fans') # 先获取一个字段的属性 在对获取的数据集在采起升序排序 t6 = Teacher.objects.filter(fans__gte=500).order_by('-fans') # 先获取一个字段的属性 在对获取的数据集在采起降序排序 # 4.查询原生sql语句 经过query进行查询 print(f"我是查询语句{str(t6.query)}") return render(request, 'learn_set.html')
View Code

 

(2)返回新的queryset的API

def start(request): """ 查询介绍 返回新的 Query API """ # 1.all() filter() order_by():排序 exclude():除了xx元素之外 reverse():反向排序 distinct():去重 # 能够用pk代替关键字 exclude除去含有关键字的信息 st_0 = Student.objects.all().exclude(pk="A同窗") # print(f"我是exclude:{st_0}") # 使用reverse的时候能够在Meta中用ordering指定排序的字段 多个ordering的时候取第一个 默认按照关键字的顺序输出 st_0_1 = Student.objects.reverse() # print(f"我是reverse:{st_0_1}") # 2.extra():给字段取别名 defer():排除一些字段 only():选择一些字段 # extra(): extra(select={"[要取的别名]": "[原来字段名]"}) st_1 = Student.objects.all().extra(select={"name": "nickname"}) # for i in st_1: # print(f"我是extra:{i.name}") st_2 = Student.objects.all().only('nickname', 'age') # print(f"我是only_query:{str(st_2.query)}") # 3.values():字典 values_list():元组 获取字典或者是元组形式的queryset # values() 输出的是dict类型的 st_3_0 = TeacherAssistant.objects.values('nickname', 'hobby') # print(f"我是values:{st_3_0}") # values_list() 输出的是元组类型的数据 st_3_1 = TeacherAssistant.objects.values_list('nickname', flat=True) # flat:将单个字段的数据直接放到列表里面 只限于获取单个数据的信息 # print(f"我是values_list:{st_3_1}") # 4.根据时间和日期获取查询集 dates:年月日 datetimes年月日时分秒查询字段多一点有时分秒 使用什么查询方式取决于定义字段的类型 # datetimes('[查询时间的字段]', 'month', order='DESC') st_4 = Course.objects.dates('online', 'year', order='DESC') # ASC 升序排列(默认) DESC降序排列 # print(f"我是dates:{st_4}") # 5.集合的运算 union():并集 intersection():交集 difference():差集 s_1 = Student.objects.filter(study_time__gte=1600) # 大于等于1500 s_2 = Student.objects.filter(study_time__lte=1500) # 小于等于1600 # print(f"我是union:{s_1.union(s_2)}") # 只支持取并集 # print(f"我是intersection:{s_1.intersection(s_2)}") # 数据库不支持 # print(f"我是difference:{s_1.difference(s_2)}") # 数据库不支持 # 6.优化查询api select_related() 一对一 多对一的优化查询 prefetch_related() 一对多 多对多的优化查询 # select_related() # 经过课程获取讲师信息 查询相关信息经过外接字段进行链接 c_1 = Course.objects.all().select_related('teacher') for c in c_1: print(f"课程信息:{c.title}--{c.teacher.nickname}--{c.teacher.fans}") # prefetch_related() 多对多 s_1 = Student.objects.filter(age__lte=30).prefetch_related('course') for s in s_1: for i in s.course.all(): # 获取到的是managerelmanage的对象 print(f"{s.nickname}--{i.title}") # 输出课程的信息 # 反向查询:根据父表查询子表 # 经过在数据段的对应关系 [字表的表名]_set能够替换为related_name的值 t_1 = Teacher.objects.get(nickname='Jack').teach.all() print(f"我是反向查询{t_1}") # 7.annotate() 使用聚合计数、求和、平均数、raw()、执行原生的SQL # 求和 sum_1 = Course.objects.values('[处理表单]').annotate(vol=Sum('[处理字段]')) sum_1 = Course.objects.values('teacher').annotate(vol=Sum('volume')) print(f"我是求和:{sum_1}") # 平均值 ave_1 = Student.objects.values('course').annotate(time=Avg('study_time')) print(f"我是求平均值:{ave_1}") # row能够写原生数据语句 里面执行原生的SQL语句 # 参考文档 # https://docs.djangoproject.com/en/2.2/topics/db/sql/
View Code

 

(3)不返回新的query的API

def start(request): """ 不返回查询集的API """ # 参考文档:https://docs.djangoproject.com/en/2.2/ref/models/querysets/#raw # 1.获取对象 get() get_or_create() first() last() latest() earliest() in_bulk() # get() 获取对象 # get_or_create() 有数据就经过get获取没有就建立数据 # first() # 第一条记录 # print(f"我是first:{Course.objects.first()}") # last() # 最后一条记录 # print(f"我是last:{Course.objects.last()}") # latest() # 最近的记录 须要在模型类里面设置 get_latest_by = [建立的字段] 表明根据建立的字段进行排序 # 也能够在排序的时候本身指定 更加方便咱们本身的操做 # print(f"我是latest{Course.objects.latest('online')}") # earliest() # 最先的记录 # print(f"我是earliest{Course.objects.earliest('update_date')}") # in_bulk() 批量返回对象 根据主键的值传递一个列表 列表中传递主键的值 # print(Course.objects.in_bulk(['Java入门课程1', 'Java入门课程2', 'python入门课程2'])) # 2.建立对象 create():建立对象 bulk_create():批量建立对象 create_or_update():若是没有就建立有就更新 # bulk_create:给函数建立一个列表 # 3.更新对象 update():更新 update_or_create():更新或建立 # update() # print(f"我是更新前的价格:{Course.objects.get(title='C++高阶课程1').price}") # Course.objects.filter(title="C++高阶课程1").update(price=568) # print(f"我是更新后的价格:{Course.objects.get(title='C++高阶课程1').price}") # 4.删除对象 delete():使用filter过滤 # print(Course.objects.filter(title="test_1").delete()) # 5.其余操做 exist():是否存在 count():统计个数 aggregate():聚合 # exist() # print(Course.objects.filter(title="test_1").exists()) # print(Course.objects.filter(title="PHP进阶课程2").exists()) # count()记录数据表中的数据个数 # print(Course.objects.count()) # annotate():和value配合使用 对分组结果进行排序 aggregate():对数据库中的数据结果进行处理 # print(Course.objects.aggregate(Max('price'), Min('price'), Avg('price'), Sum('volume'))) return render(request, 'learn_set.html')
View Code

 
(4)自定义聚类查询
1.自定义查询方法
在individual.py中加入如下代码

from django.db import models class Concat(models.Aggregate): """ORM用来分组显示其余字段 至关于group_concat""" function = 'GROUP_CONCAT' template = '%(function)s(%(distinct)s%(expressions)s)' def __init__(self, expression, distinct=False, **extra): super(Concat, self).__init__( expression, distinct='DISTINCT ' if distinct else '', output_field=models.CharField(), **extra)

 
2.引用

在views.py中的引用

from .individual import Concat def start(request): """ 自定义聚合查询 """ # 这个title对应查询结果中的key Concat里面的才是咱们须要查询的字段 course = Course.objects.values('teacher').annotate(title=Concat('title')) for c in course: print(c) return render(request, 'learn_set.html')

 
(5)F对象查询
官方文档:https://docs.djangoproject.com/en/2.2/ref/models/expressions/#django.db.models.F

def start(request): """ F查询 """ # 操做字段数据或者是将一个字段与另外一个字段进行比较 # # 将全部的价格减11 # Course.objects.update(price=F('price') - 11) # # 获取销量大于价格10倍的字段 # course = Course.objects.filter(volume__gte=F('price') * 10) # for c in course: # print(f"{c.title}--{c.price}--{c.volume}") return render(request, 'learn_set.html')

 


(6)Q对象查询
官方文档:https://docs.djangoproject.com/en/2.2/ref/models/querysets/#q-objects

def start(request): """ Q对象结合 &:and |:or :not 实现复杂的查询 """ # 查询全部Java课程 而且销量大于等于5000 print(Course.objects.filter(Q(title__icontains='java') & Q(volume__gte=5000))) # 查询全部Python语言或者是销量小于2000的课程 print(Course.objects.filter(Q(title__icontains='python') | Q(volume__lte=2000))) return render(request, 'learn_set.html')

 

 

(7)模型类实例:

class 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="粉丝数") create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) # 每个非抽象model类必须Manager添加一个实例 objects = models.Manager() class Meta: verbose_name = "讲师信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class Course(models.Model): title = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="课程名") course_type = models.CharField(choices=((0, '其余'), (1, "实战课"), (2, "免费课程")), max_length=1, default=0, verbose_name="课程类型") price = models.PositiveSmallIntegerField(verbose_name="价格") volume = models.BigIntegerField(verbose_name="销量") online = models.DateField(verbose_name="上线时间") create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) # 系统本身添加 update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) # 系统本身添加 objects = models.Manager() # 外键关联 # 多对一 多个课程对应一个讲师 teacher = models.ForeignKey(to=Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='课程讲师', related_name='teach') class Meta: verbose_name = "课程信息表" verbose_name_plural = verbose_name # 根据建立的字段进行排序 方便latest和earliest进行排序 也能够在排序时指定 # get_latest_by = 'online' def __str__(self): # get_[要展现的字段]_display()就能够输出了 如2--python入门课程1>, return f"{self.get_course_type_display()}--{self.title}" class Student(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, 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)") create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) objects = models.Manager() # 外键关联 # 多对多 学生和课程 course = models.ManyToManyField(to=Course, verbose_name='课程信息') class Meta: # 指定多个时 按第一个进行排序 # 不指定根据关键字的顺序进行排序 如在数据表中添加的数据顺序 ordering = ['study_time'] verbose_name = "学生信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class TeacherAssistant(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='昵称', ) hobby = models.CharField(max_length=30, null=True, blank=True, verbose_name='爱好', ) create_date = models.DateField(auto_now_add=True, verbose_name='建立时间', ) update_date = models.DateField(auto_now=True, verbose_name='更新时间', ) objects = models.Manager() # 外键关联 # 一对一 若是on_delete置空就要将null, blank都设置为空 teacher = models.OneToOneField(to=Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="讲师") class Meta: verbose_name = "讲师助手信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname
View Code

 

 6、总结
本篇blog简单的介绍了orm的内容,也是Django后端内容中最为重要的一个部分,其余详情请参考Django的官方文档

 

原文出处:https://www.cnblogs.com/future-dream/p/10604600.html

相关文章
相关标签/搜索