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

类——>数据表

对象——>记录

属性——>字段

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

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

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

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

2.二进制的数据

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

3.boolean类型

# 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.字符型

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

6.时间类型

# 时间日期类型
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

三、元数据
文档地址: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' # 定义数据库表空间的名字

四、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

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)

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来实现

五、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')

(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/

(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')

(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

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

Django的学习进阶(三)————ORM的更多相关文章

  1. Django的学习进阶(二)———— name

    一.问题: 在做完第一个demo的时候,由于只是基础学习,所以对于name的使用并不需要很熟练,也不用理解的很深.但是在做音乐网站的时候遇到了关于如何使用name的内容. 由于一个app中会使用到另一 ...

  2. Django的学习(三)————models

    models采用的的是类的方式,一个类对应一张表,在django中只需要对类的操作就可以完成数据表的操作,这种方式可以省去写sql语句,完成了sql语句的封装,被叫做 ORM(object relat ...

  3. Django的学习进阶(一)—— 外键的使用

    一.描述 在利用django做网络开发的时候我们会遇到一个问题就是,我们建立了多张数据表,但是多张数据表中的内容是不一样的,但是之间有着联系比如: 我有两张表,一张是记录歌曲信息的内容,一张是对歌曲操 ...

  4. 转:C#制作ORM映射学习笔记三 ORM映射实现

    现在开始实现ORM的主体模块,首先需要在项目中新建一个类,命名为DbAccess,然后在项目的引用中添加两个dll,分别是MySql.Data.dll和System.Data.SQLite.dll,这 ...

  5. The Definitive Guide To Django 2 学习笔记(三) URLconfs 和松耦合

    前面的例子体现了一个设计模式中的重要思想,松耦合. 不论我们是将/time/改成/current_time/,还是新建一个/another-time-page/同样指向views.py中的 curre ...

  6. Html5学习进阶三 Input 类型

    HTML5 新的 Input 类型 HTML5 拥有多个新的表单输入类型.这些新特性提供了更好的输入控制和验证. 本章全面介绍这些新的输入类型: email url number range Date ...

  7. Django:学习笔记(7)——模型进阶

    Django:学习笔记(7)——模型进阶 模型的继承 我们在面向对象的编程中,一个很重要的的版块,就是类的继承.父类保存了所有子类共有的内容,子类通过继承它来减少冗余代码并进行灵活扩展. 在Djang ...

  8. Django初识 学习笔记一

    Django初识 学习笔记一 mvcviewsmodelstemplate. 一 MVC框架 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(c ...

  9. Django入门到进阶-更适合Python小白的系统课程

    Django入门到进阶-更适合Python小白的系统课程 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身 ...

随机推荐

  1. git如何merge github forked repository里的代码更新

    git如何merge github forked repository里的代码更新? 问题是这样的,github里有个项目ruby-gmail,我需要从fork自同一个项目的另一个repository ...

  2. C++程序设计1(侯捷video 7-13)

     一.Big three(拷贝构造.拷贝赋值.析构函数)(video7) Big three指三个特殊函数,分别是拷贝构造函数.拷贝赋值和析构函数. 什么时候需要拷贝构造.拷贝赋值.析构函数: 当类中 ...

  3. spring boot 2.x 系列 —— spring boot 整合 redis

    文章目录 一.说明 1.1 项目结构 1.2 项目主要依赖 二.整合 Redis 2.1 在application.yml 中配置redis数据源 2.2 封装redis基本操作 2.3 redisT ...

  4. 教妹子用IDEA创建web应用,部署到Tomcat服务器

    自从上一篇原创发表之后,粉丝反应热烈.主要分两派,一派关注技术的,觉得看了那么多的公众号文章,终于找到一篇能看懂的了,于是沾沾自喜.另一派是关注妹子的,感叹自己空有一身绝技,公司里却无妹子可教,大喊可 ...

  5. 对比Hashtable,HashMap,TreeMap,谈谈对HashMap的理解

    都实现了Map接口,存储的内容是基于key-value的键值对映射,一个映射不能有重复的键,一个键最多只能映射一个值. 1.初始化的时候:HashTable在不指定容量的情况下的默认容量是11,且不要 ...

  6. Linux 安装Nginx与使用

    最近继续整理Linux相关文档.这次整理的是Nginx,这里将自己整理的详细文档做个笔记. 1.  安装环境依赖包 1. gcc 语言编译器套件. 2. pcre 兼容正则表达式的库 rewrite ...

  7. tensorflow 离线使用 fashion_mnist 数据集

    在tensflow中加载 fashion_mnist 数据集时,由于网络原因.可能会长时间加载不到或报错 此时我们可以通过离线的方式加载 1.首先下载数据集:fashion_mnist (下载后解压) ...

  8. SFC20 功能例子 注解

    谁能够把这注解一下,给大家分享一下,谢谢了 LAR1  P##SOURCE       L     B#16#10       T     LB [AR1,P#0.0]       L     B#1 ...

  9. ETL-kettle 核心执行逻辑

    一.大数据下的ETL工具是否还使用Kettle kettle 作为通用的ETL工具,非常成熟,应用也很广泛,这里主要讲一下 目前我们如何使用kettle的? 在进行大数据处理时,ETL也是大数据处理的 ...

  10. C#常用正则表达式回顾

    项目中有些时候需要用到正则表达式,但是自己对正则表达式不熟悉,每次学习完,过一段时间(长时间)不用,就又忘了,每次需要用到的时候都需要百度下,比较麻烦,这里把C#中经常用到的正则表达式做下总结. 正则 ...