August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Django数据库的操作
发布:2020年10月04日 | 作者:augustrush | 阅读量: 1847

定义模型类


  • 模型类被定义在"应用/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异常


数据库操作——增、删、改、查


增加


增加数据有两种方法。


1)save


通过创建模型类对象,执行对象的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()


2) create


通过模型类.objects.create()保存。


HeroInfo.objects.create(
    hname='沙悟净',
    hgender=0,
    hbook=book
)

# <HeroInfo: 沙悟净>


删除


删除有两种方法


1) 模型类对象delete


hero = HeroInfo.objects.get(id=1)
hero.delete()


2) 模型类.objects.filter().delete()


HeroInfo.objects.filter(id=1).delete()


修改


修改更新有两种方法


1) save


修改模型类对象的属性,然后执行save()方法


hero = HeroInfo.objects.get(hname='猪八戒')
hero.hname = '猪悟能'
hero.save()


2) update


使用模型类.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 过滤单一结果


对于过滤条件的使用,上述三个方法相同。

过滤条件的表达语法如下:


属性名__比较运算符=值 # 属性名和比较运算符间使用两个下划线,所以属性名不能包括多个下划线


1) 相等


exact:表示判等


BookInfo.objects.filter(id__exact=1)
# 可简写为:
BookInfo.objects.filter(id=1)


2) 模糊查询


contains:是否包含


BookInfo.objects.filter(btitle__contains='西游')


startswith, endswith:以指定值开头或结尾。


BookInfo.objects.filter(btitle__startswith='射')

BookInfo.objects.filter(btitle__endswith='传')


以上运算符都区分大小写,再这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.


3) 空查询


isnull: 是否为null


BookInfo.objects.filter(btitle__isnull=False)


4) 范围查询


in: 是否包含再范围内


BookInfo.objects.filter(id__in=[1,3,5])  # 查询编号为1或3或5的图书

BookInfo.objects.filter(id__in=range(1,5))  # 查询编号为1-4的图书


5) 比较查询


  • 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的图书


6) 日期查询


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日后发表的图书


F对象


如果想要比较对象的两个属性,则使用被定义再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倍评论量的图书


Q对象


多个过滤器逐个调用表示逻辑与关系,同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构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed