模型类字段类型及特殊属性
BooleanField
True/False 字段,默认值为 None
BooleanField(**options)
- 表单类型:CheckboxInput,
<input type='checkbox' ...>
CharField
字符串字段
CharField(max_length=None)
# max_length 设置最大的字符数长度限制
- 表单类型:TextInput,
<input type="text" ...>
DateField
以
datetime.date
实例表示的日期
DateField(auto_now=False, auto_now_add=False,**options)
'''
auto_now: 该值为 True 时,每次在保存数据对象时,自动设置该字段为当前时间,也可以理解为自动更新最后一次修改时间
auto_now_add: 该值为 True 时,该字段设置在第一次数据对象创建时,可以记录当前字段创建的时间值
'''
-
注意:避免矛盾,
auto_now
,auto_now_add
,default
不能同时出现,一个字段属性只能有其中一条设置,当设置了auto_now
,或auto_now_add
时,也会让该字段默认具有blank=True
(字段可以为空)属性 -
表单类型:TextInput,
<input type="text" ...>
DatetimeField
以
datetime.datetime
实例表示的日期和时间
DatetimeField(auto_now=False, auto_now_add=False,**options)
# auto_now_add: 创时使用当前时间 注册时间
# auto_now: 修改时自动更新为当前时间 用户上次登陆,修改ip
# 和 DateField 具有相同的字段属性
DecimalField
以Decimal实例表示的十进制浮点数类型
DecimalField(max_digits=None,decimal_places=None, **options)
'''
max_digits: 位数总数,包括小数点后的位数,必须大于 decimal_places 参数
decimal_places: 小数点后的数字数量,精度
'''
- 表单类型:TextInput,
<input type="text" ...>
FloatField
使用
float
实例来表示的浮点数
FloatField(**options)
- 表单类型:TextInput,
<input type="text" ...>
IntegerField
一个整数,范围由
-2147483648
到2147483647
IntegerField(**options)
字段属性
字段通用属性
choices
一个二元组的列表或元组;
元组中第一个值为真正在数据库中存储的值,第二个值为该选项的描述
该值一旦被设定,表单样式会显示选择框,而不是标准的文本框,选择框内的选项为choices
中的元组
class TestTable(models.Model):
CHAR_CHOICE = [
('H',"非常苦难"),
('M',"中等难度"),
('S',"非常简单"),
]
choicechar = modesl.CharField(max_length=1,choices=CHAR_CHOICE)
choices
字段也支持分类的写法
CHAR_CHOICE = [
('A',
(
('H',"Hard"),
)
),
('B',
(
('M',"Medium"),
)
),
…
]
分类的名称作为元组中的第一个值,元组的第二个值为该分类下的一个新的二元组序列数据
db_column
数据库中用来表示该字段的名称,如果未指定,那么 Django 将会使用Field
名作为字段名
db_index
当该值为True
时,为该字段创建索引
default
该字段默认值,可以是一个值或是一个回调函数
当是一个函数对象时,在创建新对象时,函数调用
primary_key
设置该值为True
时,该字段成为模型的主键字段,一个模型类同时只能有一个主键
如果一个表中不存在任意一个设置好的主键字段,django 会自动设置一个自增的AutoField
字段来充当主键,该值可以用pk
,id
方式获取。主键的设置还意味着,null=False
,unique=True
unique
如果该值为True,代表这个数据在当前的表中有唯一值
这个字段还会在模型层验证存储的数据是否唯一
unique 的设置也意味着当前字段具备唯一索引的创建
- 注意:
ManyToManyField
、OneToOneField
与FileField
字段不可以使用该属性
verbose_name
对于字段的一个可读性更高的名称
如果没有设置该值,字段名中的下换线转换成空格,作为当前字段的数据库中名称
模型类元选项
模型元选项
在模型类的Meta
类中,可以提供一系列的元选项,可以方便对该模型类进行属性设置或约束等
class TestTable(models.Model):
…
class Meta:
ordering = [Fields]
…
abstract
代表当前模型类为抽象基类,不会创建真正的数据表,只是为了其他模型类继承使用
abstract = True
app_label
当模型类被定义在了其他 app 下,这个属性用来描述当前表属于哪个 app 应用
app_label = "MyApp"
db_table
当前模型类所对应的表名,未设置时,django 默认将表名与 app 名由下划线组成,作为表名
需要注意这个表名为真实在数据库中所使用的,所以该元选项的使用应在数据表创建之前
如果在表已经存在的情况下去修改,会导致数据库内表与模型类表名不一致而查找不到报错
ordering
当前表中的数据存储时的排序规则,这是一个字段名的字符串,可以是一个列表或元组;
每一个字符串前可以使用"-
“来倒序排序,使用”?
"随机排序
ordering 排序规则的添加,也会增加数据库的开销
ordering = ['-birthday', 'age']
#先按照 birthday 倒序排序,再按照 age 字段进行排序。
verbose_name
一般设置该表展示时所用的名称,名称被自动处理为复数,字符串后加一个"s"
verbose_name_plural
与
verbose_name
功能相同,但是不会自动在字符串后加"s
"以表复数
设置表的复数名称
ORM的增删改查
先创建一个测试的数据库模型类
class Person(models.Model):
name = models.CharField(max_length=10,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄")
创建对象
save 创建数据
>>> from app.models import Person
>>> p1 = Person(name='张三',age=15)
>>> p1.save()
- 注意:
save
函数没有返回值
create 方法创建数据
>>> P1 = Person.objects.create(name='李四',age=20)
查找对象
通过模型类中的管理器进行数据的查询;
- all()
获取一个表中的所有数据,返回
QuerySet
数据对象
all_person = Person.objects.all()
- filter(**kwargs)
返回一个包含数据对象的集合,满足参数中所给的条件
res = Person.objects.all().filter(age__lt=16)
res = Person.objects.filter(age__lt=16)
- exclude(**kwargs)
返回一个包含数据对象的集合,数据为不满足参数中所给的条件
filter()查询会始终返回一个结果集,哪怕只有一个数据,但是有些时候,我们对于一些在数据表中的唯一数据进行查询时,可以使用更加合适的get
方法
- get(**kwargs)
获取唯一单条数据
get 获取数据只会返回一条匹配的结果,获取的数据只能在数据库中有一条
如果返回多个结果,会引发MultipleObjectsReturned
异常;如果没有任何匹配到的结果也会引发DoesNotExist
异常
Person.objects.get(pk=1)
- order_by(*field)
默认情况下,数据表使用模型类中的 Meta 中指定的 ordering 选项进行排序
也可以通过使用 order_by 函数进行查询结果的排序
Person.objects.order_by('age')
Person.objects.all().order_by('-age')
- count()
返回数据库中对应字段的个数,并且该函数永远不会引发异常
models.Person.objects.filter(age=20).count()
Person.objects.count()
使用count
函数时,还需要对数据表进行迭代访问
注意:所以有时使用已生产好的结果集,通过len*函数获取长度,这种方式效率会更高;count
方法的调用会导致额外的数据库查询
- values(*fields)
返回一个查询集结果,但是迭代访问时返回的是字典,而不是数据实例对象
models.Person.objects.all().values()
models.Person.objects.values()
链式过滤条件
- contains
大小写敏感的匹配查询,也是 like,注意转换后查询条件的两侧都有%
Person.objects.filter(name__contains='好')
- icontains
大小写不敏感的匹配查询
Person.objects.filter(name_icontains='好')
- range
在某个范围内进行查询
Person.objects.filter(id_range=(1,6))
- in
查询条件是否在给定的范围内,用小括号和中括号都可以
Person.objects.filter(id_in=(1,6))
Person.objects.filter(id_in=[1,6])
- exact
如果在查询过程中,没有提供查询类型(没有双下划线
),那么查询类型就会被默认指定为exact
,这是一种严格查找的方式,用来在数据库中查找和查询时的关键词参数完全一致的内容
Person.objects.filter(account='root')
Person.objects.filter(account__exact='root')
- iexact
忽略大小写的匹配
Person.objects.filter(account__iexact='root')
#匹配到的结果可能是 Root,ROot,ROOt,ROOT
- startswith、endswith
分别匹配开头和结尾,区分大小写
Person.objects.filter(passwd__startswith='admin')
# 匹配以 admin 开头的数据
- istartswith、iendswith
分别匹配开头和结尾,忽略大小写
Person.objects.filter(passwd__istartswith='admin')
匹配以不区分大小写的字符串 admin 为开头的数据
- gte
大于或等于
Person.objects.filter(reg_data__gte=datetime.date.today)
- lte
小于或等于
Person.objects.filter(reg_data__lte=datetime.date.today)
修改对象
获取到对应的数据实例之后,通过.
的方式访问数据实例中的属性,进行数据的字段修改,修改之后通过save方法对实例进行入库的保存
p = models.Person.objects.get(pk=1)
p.age = 21
p.save()
对过滤出的结果链式调用update()
函数,这样的修改,类似批量修改,update
函数会返回成功修改的个数
models.Person.objects.filter(age__gt=100).update(age=25)
# 将所有年纪小于 100 的人的年纪改为 20
删除对象
对于普通的单表数据删除,获取到数据实例对象后调用内置的delete()
函数即可
models.Person.objects.get(pk=1).delete()
- 注意:删除一条数据之后,默认占有的主键 ID 值并不会被下一个新插入的值所占用
比如 1,2,3,4;删除掉 3 之后,剩下:1,2,4;下一个值存储时,id 是 5,3 不会被复用
ORM的Q、F查询
语法如下:
from django.db.models import F
F('属性名') # 注意:属性名是字符串形式
1. 查询阅读量大于评论量的图书
Book.objects.filter(bread__gt=F('bcomment'))
Users.objects.filter(age__lt=F('id'))
2. 查询阅读量是评论量2倍的图书
Book.objects.filter(bread=F('bcomment')*2)
3. 查询阅读量比评论量多100的图书
Book.objects.filter(bread=F('bcomment')+100)
逻辑运算
from django.db.models import Q
Q(属性名__运算符=值) # 注意: 属性名不是字符串,不能加引号
1 查询id阅读量大于20且id小于3的图书
Book.objects.filter(bcomment__gt=20).filter(id__lt=3) # 多个过滤器连续操作
Book.objects.filter( Q(bcomment__gt=20) & Q(id__lt=3) ) # 使用Q对象和逻辑运算符
2 查询阅读量大于20,或编号小于3的图书
Book.objects.filter( Q(bcomment__gt=20) | Q(id__lt=3) ) # 只能使用Q对象
QuerySet是什么
- all():返回所有数据。
- filter():返回满足条件的数据。
- exclude():返回满足条件之外的数据。
- order_by():对结果进行排序。