一、ORM简介
MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库。
- ORM是“对象-关系-映射”的简称,主要任务是:
- 1)根据对象的类型生成表结构
- 2)将对象、列表的操作,转换为sql语句
- 3)将sql查询到的结果转换为对象、列表
这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动。
Django中的模型包含存储数据的字段和约束,对应着数据库中唯一的表。
二、表的常用字段和选项
常用的表字段
AutoField 自动增值的id字段 primary_key=True 为必设置选项 |
BigAutoField 自动增值的id字段 支持 1 到 9223372036854775807,之间的序号 |
BigIntegerField 长整形字段 从 -9223372036854775808 到9223372036854775807 的整数 |
BinaryField 二进制字段 存储内存二进制数据,以 python bytes 对象来访问 |
BooleanField 布尔值字段 如果许可空的布尔值输入,换用 NullBooleadField |
CharField可变长字符串字段 max_length 有最大输入选项为必须设置的选项 |
DateField日期字段 auto_now:每一次保存对象时,Django 都会自动将该字段的值设置为当前时间。一般用来表示 "最后修改" 时间。要注意使用的是当前日期,而并非默认值,所以 不能通过重写默认值的办法来改变保存时间。 auto_now_add:在第一次创建对象时,Django 自动将该字段的值设置为当前时间,一般用来表示对象创建时间。它使用的同样是当前日期,而非默认值 |
DateTimeField 有时刻的日期字段 auto_now=False auto_now_add=False 当auto_now或者auto_now_add设置为True时,字段会有editable=True和blank=True的设定 |
models.DecimalField(..., max_digits=5, decimal_places=2) ; 固定精度的十进制数的字段。 它有两个必须的参数 max_digits:数字允许的最大位数 decimal_places:小数的最大位数 例如,要存储的数字最大值是999,而带有两个小数位,你可以使用
|
DurationField 日期时间增量型字段,存储着python timedelta 类数据 |
EmailField 邮件字段 max_length |
FileField 文件字段 |
FilePathField 文件路径字段 |
FloatField 小数字段 |
ImageField 图片字段 |
IntegerField 整数字段 |
GenericIPAddressField ip地址字段 |
NullBooleanField 许可null的布尔值字段 |
PositiveIntegerField 0 到 2147483647,支持所有数据库取值范围的安全整数。 |
PositiveSmallIntegerField 0 到 32767 支持所有数据库取值范围的安全短整数。 |
SlugField |
SmallIntegerField 短整形字段 |
TextField 备注型字段,用于存储复杂文本 |
TimeField 时间字段 |
URLField 网址字段 |
UUIDField Python UUID 数据对象,一个32位长度的ID字符串 |
映射字段 ForeignKeyField 一对多字段 |
映射字段 ManyToManyField 多对多字段 |
映射字段 OneToOneField 一对一字段 |
|
上文中提及了表字段和表字段的选项,罗列了所有常用的字段和字段选项,但因为教案到此处,还没有涉及表单功能的讲解。所以有些字段选项,还不好举例说明用法。后续到表单的知识章节,再做讲解。
ForeignKeyField、ManyToManyField、以及OneToOneField 这三个字段是映射字段。后续的章节才会讲到,他们有非常数量级的业务流程,非这一个章节能说明白。这里就提及有他们而已。
再有如 BigAutoField 和AutoField一样,只是一个有效值的范围大些,一个小些。BigIntergerField和IntergerField也是这样的一对,一个有效值范围大,一个小。所以代码举例时没有都举例。自己脑补一下。应该说自己手动输入代码玩玩。
虽然章节还未涉及后台知识点,但我们还是可以先睹为快框架的强大。
常用的表字段选项
这里只做一个列举,后头有表字段选项的用法。
null | 不设置时默认设置为False。设置为True时,数据库表字段中将存入NULL的记录。 |
blank | 默认设置为False。设置为True时,表字段许可无任何输入。设置为False 时,表字段为必须输入的字段
|
choices | 备选设置。选择列表选项,如果设置后,该字段的表单必然会是下拉选择的。这个值必须是一个有小括号构成的元组,每个元组前一个字段将存入数据库,后一个字段是显示给用户看的。 |
default | 默认值,设置后在用户无输入时,表字段将以这个选项的内容来存储到数据库字段 可以为python 支持的任意数据对象 |
editable | 如何设置为False,将不会参与到表单的验证。默认是设置为True的 |
error_messages | 这个选项实现校验时的错误提示。是字典结构的内容。 |
help_text | 在表单中形成输入提示内容 |
primary_key | 主键,设置为 True ,该字段将启用为主键。 默认是 False |
unique | 设置为 True 启用不存在重复值输入的设定,默认为False |
unique_for_date
| 设定日期不存在重复输入,默认为False
|
verbose_name | 字段的文本标签 |
validators | 校验选项,用来配置校验的方法,构成的列表。 |
max_length | 最大输入字符串的长度 |
min_length | 最少输入字符串的长度 |
|
|
三、模型类的创建
from django.db import models
from datetime import datetime
# Create your models here.
class StudentInfo(models.Model):
name = models.CharField(max_length=20,verbose_name="学生姓名")
age = models.IntegerField(default=18,verbose_name="学生年龄")
gender = models.CharField(choices=(('girl','女'),('boy','男')),max_length=6,default='girl',verbose_name="学生性别")
stuid = models.CharField(max_length=20,verbose_name="学生学号")
address = models.TextField(verbose_name="学生地址")
height=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="学生身高")
# image =models.ImageField(upload_to='user/%y/%m/%d',max_length=100,verbose_name="学生头像")
add_time = models.DateTimeField(default=datetime.now,verbose_name="添加时间")
is_delete = models.BooleanField(default=False,verbose_name="是否删除")
def__str__(self):
return self.name
class Meta:
#设置表在数据库当中显示的名字,默认是app名字_模型类名小写形式
db_table ='studentinfo'
#设置默认以某个字段进行排序,-表示,倒序排序
# ordering =['-age']
#设置表名在admin后台显示的名字,下面是复数形式也用这个名字
verbose_name ='学生信息'
verbose_name_plural =verbose_name
四、单表的增删改查
1、增
第一种方法:
先实例化模型类对象,对模型类对象的属性赋值,然后save()保存。
例如:
#实例化数据模型类对象
zhaoliying = StudentInfo()
#对象属性赋值
zhaoliying.name ='赵丽颖'
zhaoliying.age =30
zhaoliying.address ='廊坊'
zhaoliying.stuid ='001'
zhaoliying.height =170
#保存对象,保存对象之后才会真正的存入数据库
zhaoliying.save()
第二种方法
通过模型默认管理器objects的接口方法create()去创建对象做增加
这种方法执行完成后就会在数据库中存在数据,不需要save.
StudentInfo.objects.create(name='赵丽颖',age=30,stuid='001',address='廊坊',height=179.01)
注意:第一种方法,必须要进行save()保存后,才会将数据真正的存在数据库表当中,因此在save()之前,我们可以对模型类对象属性做任何操作。
2、查
通过模型默认管理器objects的接口方法去查找
第一种:获取表内所有的数据
all_students= StudentInfo.objects.all()
这个all_students 是一个由所有数据对象组成了一个queryset类型,类似于列表,我们可以把它当作列表来使用
第二种:根据条件查找特定的数据
我们也可以根据某些特定的条件去查找过滤特定的数据。例如:
filter_students =StudentInfo.objects.filter(age=30)
可以查找到年龄为30岁的学生组成的一个列表。如果有数据,那么就是一个由这些数据组成的列表,如果没有数据就是一个空列表。
第三种:根据条件获取一个数据
我们可以使用下面这个get方法获取到符合条件的一个数据对象,它获取到的不是列表,是一个对象。如果符合条件的数据对象很多,那么仅返回第一个数据对象。如果没有符合条件的数据对象,那么会抛出异常,因此我们要用这个方法去查找数据的时候,一般需要异常处理。
student = StudentInfo.objects.get(age=30)
注:一般我们不主张用get方法获取一个对象,因为可能有异常发生,我们可以巧妙的使用filter避免异常,filter返回的是一个数据对象组成的列表,而get返回的直接是这个数据对象。
假设数据库当中只有一条符合条件的数据:我们可以在filter的结果后面加上【0】,就代表是get返回的单个数据对象了,并且filter没有数据对象不会发生异常。
3、改
数据的改一般都是建立在查找的基础之上的,当我们需要修改一个数据的时候,都需要先把待修改的数据对象查找到,然后再通过相应的修改方法去修改。
例如:我们下面这个例子是,把zhaoliying这个学生的年龄改成31岁,那么我们首先要找到这个学生,然后再去修改
第一种方法:
①、先找到这个对象:
zhaoliying = StudentInfo.objects.filter(name=’zhaoliying’)[0]
②、修改这个对象的年龄属性
zhaoliying.age = 31
③、需要去保存这个对象才能让数据库中数据生效
zhaoliying.save()
第二种方法:
StudentInfo.objects.filter(name=’zhaoliying’).update(age=31)
这个方法使用的模型类的管理器接口的更新方法,但是这个方法只能对列表起作用,不能对单个数据对象起作用,我们在使用的时候需要注意,并且如果我们修改的列表当中数据较多,那么所有的这些数据都会被修改,因为这个方法作用的是整个列表。
4、删除
删除一个数据对象和删除一个列表都是可以的。删除的时候需要注意:
删除一个数据对象:
student =StudentInfo.objects.filter(name=’zhaoliying’)[0]
student.delete()
也可以直接删除一个列表所有的数据
StudentInfo.objects.filter(age=30).delete()