![cover](https://img-blog.csdnimg.cn/img_convert/7f5c58ef2b134719a11b9e8f8d4b7321.png)
Django后端框架(六)ORM字段|DjangoShell|创建数据|查询操作
等同于 SELECT * FROM MyModel WHERE country in ('中国', '日本', '韩国')MyModel.objects.filter(country__in=['中国', '日本', '韩国'])使用内部Meta类来给模型赋予属性,Meta类下有很多内建的类属性,可对模型类做一些控制(控制表相关属性)MyModel.objects.create(属性1=值1, 属
【回顾·创建模型类流程】
- 创建应用
- 在应用下的models.py中编写数据类
- 迁移同步 makemigrations和migrate
****任何关于表结构的修改,务必在对应模型类上修改
****修改过字段选项(添加or更改)均要执行makemigrations和migrate
【模型类的字段类型】
- BooleanField()
- 数据库类型:tinyint(1)
- 在编程语言中:使用True或False来表示值
- 在数据库中:使用1或0来表示具体的值
- CharField()
- 数据库类型:varchar
- 注意:必须要指定max_length参数值!!!
- DateField()
- 数据库类型:date
- 作用:表示日期
- 参数:(以下三个参数只能设置一个为True)
- auto_now:将 每次保存对象时的时间 自动设置为该字段的时间(取值True/False)
- auto_now_add:将 对象第一次被创建时的时间 自动设置为该字段的时间(取值True/False)
- default:自定义时间(取值:字符串格式时间,如:'2019-6-1')
- DateTimeField()
- 数据库类型:datetime(6)
- 作用:表示日期和时间
- 参数:同DateField()
- FloatField()
- 数据库类型:double
- 编程语言中和数据库中都使用小数表示值
- DecimalField()
- 数据库类型:decimal(x, y)
- 在编程语言中:使用小数表示该列的值
- 在数据库中:使用小数
- 参数:
- max_digits:位数总数,包括小数点后的位数。该值必须大于等于decimal_places的值
- decimal_places:小数点后的位数
- EmailField()
- 数据库类型:varchar(Django中设置了正则)
- 编程语言与数据库中都使用字符串
- IntegerField()
- 数据库类型:int
- 编程语言与数据库中都使用整数
- ImageField()
- 数据库类型:varchar(100)
- 作用:在数据库中为了保护图片的路径
- 编程语言和数据库中使用字符串
- TextField()
- 数据库类型:longtext
- 作用:表示不定长的字符数据
【模型类的字段选项】
字段选项:指定创建的列的额外的信息
*允许出现多个字段选项,多个选项之间使用英文逗号隔开
- primary_key:设置为True时,表示该列为主键,如果指定一个字段为主键,则此数据库表不会自动创建id字段。
- blank:设置为True时,字段可以为空;设置为False时,字段必须填写。
- null:设置为True时,表示该列的值允许为空。此字段选项默认为False,为False时,建议加入default选项来设置默认值。
- default:设置所在列的默认值,如果字段选项null=False,则建议添加此项。
- db_index:设置为True时,表示为该列增加索引。
- unique:设置为True时,表示该字段在数据库中的值必须是唯一的(不能重复出现)。
- db_column:可以指定列的名称,如果不指定,则采用属性名作为列名。
- verbose_name:设置此字段在admin界面上的显示名称
# 样例:创建一个属性,表示用户名称,长度30个字符,必须唯一,不能为空,添加索引
name = models.CharField(max_length=30, unique=True, null=False, db_index=True)
【Meta类】
使用内部Meta类来给模型赋予属性,Meta类下有很多内建的类属性,可对模型类做一些控制(控制表相关属性)
>样例1:将表名bookstore_book修改为book
# file: bookstore/models.py
from django.db import models
class Book(models.Model):
title = models.CharField("书名", max_length=50, default='')
price = models.DecimalFiedl("定价", max_digits=7, decimal_places=2, default=0.0)
class Meta:
db_table = 'book' # 修改了当前模型类对应的表名
<<常见问题汇总>>
1、当执行python3 manage.py makemigrations时,出现如下迁移错误:
错误原因:
- 当对模型类新添加一个字段时可能出现该错误
- 原理是:添加新字段后,数据库不知道原来已有数据对于新建字段该如何赋值,所以新增字段时,务必要添加default默认值
处理方法:
- 方案1:进入到shell中,手动输入一个默认值
- 方案2(推荐):退出当前生成迁移文件的过程,自己去修改models.py,新增加一个'default=XXX'的缺省值
2、数据库的迁移文件混乱问题
错误原因:数据库中django_migrations表记录了migrate的全过程,项目各应用中的migrate文件应与之对应,否则migrate会报错
解决方案:
- 方案1:删除所有migrations中所有的000?_XXX.py(__init__.py除外)
- 方案2:删除数据库(命令:drop database 数据库名)
【ORM基本操作】
基本操作包括增删改查操作,即CRUD。
ORM CRUD核心是:模型类.管理器对象
【管理器对象】
每个继承自models.Model的模型类,都会有一个objects对象被同样继承下来,这个对象就叫管理器对象。
数据库的增删改查操作可以通过模型的管理器实现。
【ORM基本操作-创建数据】
Django ORM 使用一种直观的方式把数据库表中的数据表示成Python对象,
创建数据中每一条记录就是创建一个数据对象。
- 方案1:
MyModel.objects.create(属性1=值1, 属性2=值2, ...)
若运行成功,则返回创建好的实体对象;若失败,则立即抛出异常
- 方案2:创建MyModel实例对象,并调用save()进行保存
obj = MyModel(属性1=值1, 属性2=值2, ...)
obj.属性=值 # 此行按照需求可有可无,可临时补充属性值
obj.save()
【Django Shell】
在Django提供了一个交互式的操作项目叫Django Shell,它能够在交互模式下用项目工程的代码执行相应的操作。
利用Django Shell可以代替编写view的代码来进行直接操作。
**注意:项目代码发生变化时,要重新进入Django Shell,保证代码最新
- 启动方式:
python3 manage.py shell
- 在Django Shell中创建数据:方案1(**注意:一定要导入模型类!!)
- 在Django Shell中创建数据:方案2
【ORM基本操作-查询操作】
数据库的查询需要使用管理器对象进行,
通过MyModel.objects管理器方法调用查询方法。
方法 | 说明 |
all() | 查询全部记录,返回QuerySet查询对象 |
get() | 查询符合条件的单一记录 |
filter() | 查询符合条件的多条记录 |
exclude() | 查询符合条件之外的全部记录 |
... | ... |
【查询方法】
- all()
- 用法:MyModel.objects.all()
- 作用:查询MyModel实体中所有的数据(等同于SELECT * FROM mytabel)
- 返回值:QuerySet容器对象,内部存放MyModel实例(类似类数组对象)
******可以在模型类中定义__str__方法,自定义QuerySet中的输出格式
如:在Book模型类(models.py中Book类)下定义如下:
def __str__(self):
return '%s_%s_%s_%s'%(self.title, self.price, self.pub, self.market_price)
则在Django Shell中可得到如下显示输出:
- values('列1', '列2', ...)
- 用法:MyModel.objects.values(...)
- 作用:查询部分列的数据并返回(等同于SELECT 列1,列2 FROM mytable)
- 返回值:QuerySet,返回查询结果容器,容器内存字典,每个字典代表一条数据,格式为{'列1':值1, '列2':值2}
- values_list('列1', '列2', ...)
- 用法:MyModel.objects.values_list(...)
- 作用:返回元组形式的查询结果(等同于SELECT 列1,列2 FROM mytable)
- 返回值:QuerySet容器对象,内部存放元组,会将查询出来的数据封装到元组中,再封装到查询集合QuerySet中
- order_by()
- 用法:MyModel.objects.order_by('-列','列')
- 作用:与all()方法不同,它会用SQL语句的ORDER BY子句对查询结果进行根据某个字段选择性的进行排序
- 说明:默认是按照升序排序,降序排序则需要在 列前增加 '-'号表示
>方法也可以组合起来使用,如:
value()和order_by()组合:
>使用.query可以查看SQL语句,如:
【条件查询】
- filter(条件)
- 语法:MyModel.objects.filter(属性1=值1, 属性2=值2)
- 作用:返回包含此条件的全部的数据集
- 返回值:QuerySet容器对象,内部存放MyModel实例
- 说明:当有多个属性的条件时为“与”关系
- exclude(条件)
- 语法:MyModel.objects.exclude(条件)
- 作用:返回不包含此条件的全部的数据集
- get(条件)
- 语法:MyModel.objects.get(条件)
- 作用:返回满足条件的唯一一条数据
- 说明:该方法只能返回一条数据。查询结果多于一条数据则抛出Model.MultipleObjectsReturned异常;查询结果如果没有数据则抛出Model.DoesNotExist异常
【查询谓词】
定义:做更灵活的条件查询时需要使用查询谓词
*每一个查询谓词是一个独立的查询功能
- __exact:等值匹配
- __contains:包含指定值
- __startswith:以指定值开始
- __endswith:以指定值结束
- __gt:大于指定值
- __gte:大于等于指定值
- __lt:小于指定值
- __lte:小于等于指定值
- __in:查找数据是否在指定范围内
- __range:查找数据是否在指定的区间范围内
# 等同于 SELECT * FROM MyModel WHERE id=1
MyModel.objects.filter(id__exact=1)
# 等同于 SELECT * FROM MyModel WHERE name LIKE '%w%'
MyModel.objects.filter(name__contains='w')
# 等同于 SELECT * FROM MyModel WHERE age>50
MyModel.objects.filter(age__gt=50)
# 等同于 SELECT * FROM MyModel WHERE country in ('中国', '日本', '韩国')
MyModel.objects.filter(country__in=['中国', '日本', '韩国'])
更多推荐
所有评论(0)