ORM之单表操作
ORM介绍
ORM概念
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。
ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。
ORM在业务逻辑层和数据库层之间充当了桥梁的作用。
ORM优势
ORM解决的主要问题是对象和关系的映射。它通常将一个类和一张表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。
ORM提供了对数据库的映射,不用直接编写SQL代码,只需操作对象就能对数据库操作数据。
让软件开发人员专注于业务逻辑的处理,提高了开发效率。
ORM劣势
ORM的缺点是会在一定程度上牺牲程序的执行效率。
ORM的操作是有限的,也就是ORM定义好的操作是可以完成的,一些复杂的查询操作是完成不了。
ORM用多了SQL语句就不会写了,关系数据库相关技能退化...
字段
常用字段
AutoField
自增的整形字段,必填参数primary_key=True,则成为数据库的主键。无该字段时,django自动创建。
一个model不能有两个AutoField字段。
IntegerField
一个整数类型。数值的范围是 -2147483648 ~ 2147483647。
CharField
字符类型,必须提供max_length参数。max_length表示字符的长度。
DateField
日期类型,日期格式为YYYY-MM-DD,相当于Python中的datetime.date的实例。
参数:
- auto_now:每次修改时修改为当前日期时间。
- auto_now_add:新创建对象时自动添加当前日期时间。
auto_now和auto_now_add和default参数是互斥的,不能同时设置。
DatetimeField
日期时间字段,格式为YYYY-MM-DD HH:MM:ss[.uuuuuu],相当于Python中的datetime.datetime的实例。
BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True
BigIntegerField(IntegerField)
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field)
- 可以为空的布尔值
TextField(Field)
- 文本类型
BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True
注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models
class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)
class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制
URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
FloatField(Field)
- 浮点型
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
BinaryField(Field)
- 二进制类型`
自定义char类型字段
class MyCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return 'char(%s)' % self.max_length
使用自定义char类型字段
class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=25)
# 使用自定义的char类型的字段
cname = MyCharField(max_length=25)
字段参数
null 数据库中字段是否可以为空
db_column 数据库中字段的列名
default 数据库中字段的默认值
primary_key 数据库中字段是否为主键
db_index 数据库中字段是否可以建立索引
unique 数据库中字段是否可以建立唯一索引
unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month 数据库中字段【月】部分是否可以建立唯一索引
unique_for_year 数据库中字段【年】部分是否可以建立唯一索引
verbose_name Admin中显示的字段名称
blank Admin中是否允许用户输入为空
editable Admin中是否可以编辑
help_text Admin中该字段的提示信息
choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息;
字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
如:{'null': "不能为空.", 'invalid': '格式错误'}
单表查询
必知必会13条
# 返回对象列表
all() # 获取所有的数据对象
filter(**kwargs) # 包含了所给筛选条件相匹配的对象
exclude(**kwargs) # 包含了所给筛选条件不匹配的对象
values(*field) # 返回一个ValueQuerySet, 运行得到可迭代的字典序列
values_list(*field) # 与values()相似, 返回一个元组序列
order_by(*field) # 对查询结果排序, (-)负号为降序
reverse() # 对查询结果反向排序, (在已定义顺序调用, 在model类的Meta中指定ordering 或调用order_by()方法)
distinct() # 从返回结果剔除重复记录
# 返回对象
get(**kwargs) # 返回所给筛选条件相匹配的对象, 结果只有一个, 对象多个或没有会报错
first() # 返回第一条记录
last() # 返回最后一条记录
# 返回布尔值
exists() # 包含数据返回True, 否则返回False
# 返回数字
count() # 返回数据库中匹配的(QuerySet)的对象数量
单表的双下划线(同一个表中)
# 获取个数
models.Tb1.objects.filter(name='seven').count()
# 大于、小于
models.Tbl.objects.filter(id__gt=1) # 获取id大于1的值
models.Tbl.objects.filter(id__gte=1) # 获取id大于等于1的值
models.Tbl.objects.filter(id__lt=10) # 获取id小于10的值
models.Tbl.objects.filter(id__gte=10) # 获取id小于等于10的值
models.Tbl.objects.filter(id__lt=10,id__gt=1) # 获取大于1且小于10的值
# 成员判断in
models.Tb1.objects.filter(id__in=[11,22]) # 获取id等于11,22的数据
models.Tb1.objects.exclude(id__in=[11,22]) # not in
# 是否为空 isnull
models.Tb1.objects.filter(pub_date__isnull=True)
# 包含contains
models.Tb1.objects.filter(name__contains="ven") # 获取字段包含'ven'的
models.Tb1.objects.filter(name__icontains="Ven")# 大小写不敏感
models.Tb1.objects.exclude(name__icontains="ven")
# 范围 range
models.Tb1.objects.filter(id__range=[1,2]) # 范围bettwen and
# 其他类似
startswith,istartswith, endswith, iendswith,
models.Tb1.objects.filter(name__startswith='j') # 以j开头的名字
# 获取年份
models.Tb1.objects.filter(data__year='2019')
models.Tb1.objects.filter(name__contains="2018-01")