模型类被定义在"应用/models.py"文件中。
模型类必须继承自Model类,位于包django.db.models中。
1) 数据库表名
模型类如果未指明表名,Django默认以小写app应用名_小写模型类名
为数据库表名。
可通过class Meta
内的db_table
指明数据库表名。
2) 关于主键
django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,django不会再创建自动增长的主键列。
默认创建的主键列属性为id,使用中可以用pk代替
3) 属性命名限制
不能是python的保留关键字。
不允许使用连续的下划线,这是由django的查询方式决定的。
定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性名 = models.字段类型(选项)
4) 字段类型
类 型 | 说 明 |
---|---|
AutoField | 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性 |
BooleanField | 布尔字段,值为True或False |
NullBooleanField | 支持Null、True、False三种值 |
CharField | 字符串,参数max_length表示最大字符个数 |
TextField | 大文本字段,一般超过4000个字符时使用 |
IntegerField | 整数 |
DecimalField | 十进制浮点数,参数max_digits表示总位数,参数deciaml_places表示小数位数 |
FloatField | 浮点数 |
DateField | 日期,参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”的时间戳,它总是使用当前日期,默认为False;参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False;参数atuo_now_add和auto_now是相互排斥的,组合将发生错误 |
TimeField | 时间,参数同DateField |
DateTimeField | 日期时间,参数同DateField |
FileField | 上传文件字段 |
ImageField | 继承于FileField,对上传的内容进行校验,确保是有效的图片 |
5) 选项
选 项 | 说 明 |
---|---|
null | 如果为True,表示允许为空,默认值是False |
blank | 如果为True,则该字段允许为空白,默认值是False |
db_column | 字段的名称,如果未指定,则使用属性的名称 |
db_index | 如果为True,则在表中会为此字段创建索引,默认值是False |
default | 设置字段默认值 |
primary_key | 如果为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用 |
unique | 如果为True,这个字段再表中必须有唯一值,默认值是False |
null是数据库范畴的概念,blank是表单验证范畴的概念
6) 外键
在设置外键时,需要通过on_delete
选项指明主表删除数据时,对于外键引用表数据如何处理,再django.db.models中包含了可选常量:
CASCADE级联,删除主表数据时连通一起删除外键表中数据
PROTECT保护,通过抛出ProtectedError
异常,来阻止删除主表中被外键应用的数据
SET_NULL设置为NULL,仅在该字段null=True允许为null时可用
SET_DEFAULT设置为默认值,仅在该字段设置了默认值时可用
SET()设置为特定值或者调用特定方法
DO_NOTHING 不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError
异常
增加数据有两种方法。
通过创建模型类对象,执行对象的save()方法保存到数据库中。
from datetime import date
book = BookInfo(
btitle='西游记',
bpub_date=date(1988,1,1),
bread=10,
bcomment=10
)
book.save()
hero = HeroInfo(
hname='孙悟空',
hgender=0,
hbook=book
)
hero.save()
hero2 = HeroInfo(
hname='猪八戒',
hgender=0,
hbook_id=book.id
)
hero2.save()
通过模型类.objects.create()保存。
HeroInfo.objects.create(
hname='沙悟净',
hgender=0,
hbook=book
)
# <HeroInfo: 沙悟净>
删除有两种方法
hero = HeroInfo.objects.get(id=1)
hero.delete()
HeroInfo.objects.filter(id=1).delete()
修改更新有两种方法
修改模型类对象的属性,然后执行save()方法
hero = HeroInfo.objects.get(hname='猪八戒')
hero.hname = '猪悟能'
hero.save()
使用模型类.objects.filter().update(),会返回受影响的行数
HeroInfo.objects.filter(hname='沙悟净').update(hname='沙僧')
# 1
get 查询单一结果,如果不存在则会抛出模型类.DoesNotExist异常。
all 查询多个结果。
count 查询结果数量。
BookInfo.objects.all()
BookInfo.objects.get(id=3)
BookInfo.objects.get(pk=3)
BookInfo.objects.count()
实现SQL中的where功能,包括
filter 过滤出多个结果
exclude 排除掉符合条件剩下的结果
get 过滤单一结果
对于过滤条件的使用,上述三个方法相同。
过滤条件的表达语法如下:
属性名__比较运算符=值 # 属性名和比较运算符间使用两个下划线,所以属性名不能包括多个下划线
exact:表示判等
BookInfo.objects.filter(id__exact=1)
# 可简写为:
BookInfo.objects.filter(id=1)
contains:是否包含
BookInfo.objects.filter(btitle__contains='西游')
startswith, endswith:以指定值开头或结尾。
BookInfo.objects.filter(btitle__startswith='射')
BookInfo.objects.filter(btitle__endswith='传')
以上运算符都区分大小写,再这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.
isnull: 是否为null
BookInfo.objects.filter(btitle__isnull=False)
in: 是否包含再范围内
BookInfo.objects.filter(id__in=[1,3,5]) # 查询编号为1或3或5的图书
BookInfo.objects.filter(id__in=range(1,5)) # 查询编号为1-4的图书
gt
:大于(greater then)
gte
:大于(greater then equal)
lt
:大于(less then)
lte
:大于(less then equal)
不等于的运算符,使用exclude()
过滤器
BookInfo.objects.filter(id__gt=3) # 查询编号大于3的图书
BookInfo.objects.filter(id__gte=3) # 查询编号大于等于3的图书
BookInfo.objects.filter(id__lt=3) # 查询编号小于3的图书
BookInfo.objects.filter(id__lte=3) # 查询编号小于等于3的图书
BookInfo.objects.exclude(id=3) # 查询编号不等于3的图书
year、month、day、week_day、hour、minute、second: 对日期时间类型的属性进行运算。
BookInfo.objects.filter(bpub_date__year=1980) # 查询1980年发表的图书
BookInfo.objects.filter(bpub_date__gt=date(1990,1,1)) # 查询1990年1月1日后发表的图书
如果想要比较对象的两个属性,则使用被定义再django.db.models
中的F
对象
语法如下:
F(属性名)
from django.db.models import F
BookInfo.objects.filter(bread__gte=F('bcomment')) # 查询阅读量大于等于评论量的图书
可以在F对象上使用算数运算。
BookInfo.objects.filter(bread__gt=F('bcomment') * 2) # 查询阅读量大于2倍评论量的图书
多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字
# 查询阅读量大于20,并且编号小于3的图书
BookInfo.objects.filter(bread__gt=2, id__lt=3)
# 或
BookInfo.objects.filter(bread__gt=2).filter(id__lt=3)
如果需要实现逻辑或or的查询,需要使用Q()对象结合|
运算符,Q对象被定义再django.db.models中。
语法如下:
Q(属性名__运算符=值)
# 查询阅读量大于20
from django.db.models import Q
BookInfo.objects.filter(Q(bread__gt=20))
Q对象可以使用&、|连接。&表示逻辑与,|表示逻辑或
# 查询阅读量大于20或编号小于3的图书
BookInfo.objects.filter(Q(bread__gt=20) | Q(id__lt=3))
Q对象前可以使用~操作符,表示非not。
# 查询编号不等于3的图书
BookInfo.objects.filter(~Q(pk=3))
使用aggregate()
过滤器调用聚合函数。聚合函数包括:Avg平均,Count数量,Max最大,Min最小,Sum求和,被定义在django.db.models中。
from django.db.models import Avg, Count, Max, Min, Sum
# 查询图书的总阅读量
BookInfo.objects.aggregate(Sum('bread'))
# 查询图书的阅读量的平均值
BookInfo.objects.aggregate(Avg('bread'))
# 查询图书的阅读量最大值
BookInfo.objects.aggregate(Max('bread'))
# 查询图书的阅读量最小值
BookInfo.objects.aggregate(Min('bread'))
aggregate的返回值是一个字典类型,格式如下:
{'属性名__聚合类小写' : 值} 如:{'bread_sum': 3}
使用count时一般不使用aggregate()过滤器。
BookInfo.objects.count() count函数的返回值是一个数字。
使用order_by对结果进行排序
BookInfo.objects.all().order_by('bread') # 升序
BookInfo.objects.all().order_by('-bread') # 降序
由一到多
的访问语法:
一对应的模型类对象.多对应的模型类名小写_set
b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()
由多到一
的访问语法:
多对应的模型类对象.多对应的模型类中的关系类属性名
h = HeroInfo.objects.get(id=1)
h.hbook
访问一对应
的模型类关联对象的字段语法:
多对应的模型类对象.关联类属性名.字段名
h = HeroInfo.objects.get(id=1)
h.hbook.id
h.hbook.btitle
由多模型类条件查询一模型类数据:
语法如下:
关联模型类名小写__属性名__条件运算符=值
注意:如果没有__运算符
部分,表示等于。
# 查询图书,要求图书英雄为“孙悟空”
BookInfo.objects.filter(heroinfo__hname='孙悟空')
# 查询图书,要求图书中英雄的描述包含“八”
BookInfo.objects.filter(heroinfo__hcomment__contains='八')
由一模型类条件查询多模型类数据:
语法如下:
一模型类关联属性名__一模型类属性名__条件运算符=值
注意:如果没有__运算符
部分,表示等于。
# 查询书名为“天龙八部”的所有英雄
HeroInfo.objects.filter(hbook__btitle='天龙八部')
# 查询图书阅读量大于30的所有英雄
HeroInfo.objects.filter(hbook__bread__gt=30)
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建