python模型训练框架_[Python] Django框架入门2——深入模型

说明:

本文主要深入了解模型(models.py),涉及ORM简介、模型定义、模型成员、模型查询、自连接等。需要一定基础,可以先走一走基本入门流程。

附录一使用mysql数据库,附录二Django开发流程。

目录:

一、ORM简介

ORM简介

二、模型定义

1、基本模型

2、字段类型

3、字段选项

4、关系

5、元选项

三、模型成员

1、查询

2、Django默认的管理器

3、自定义管理器

四、模型查询

1、查询集

2、字段查询

3、

五、自连接

附录一:使用mysql

附录二:Django开发流程

一、ORM简介(引用,详情请查阅相关文档)

ORM(Object Relational Mapping)即是"对象-关系-映射"的简称,是MVC框架一个重要的部分(Django也支持ORM),它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置可以轻松更换数据库。

ORM的作用:

根据对象的类型生成表结构

将对象、列表的操作,转换成sql语句

将sql查询到的结果转换为对象、列表

使用ORM主要方便开发人员,极大减轻开发人员的工作量,避免手写sql语句出现的各种问题。

Django中的模型包含存储的字段和约束,对应着数据库中唯一的表。

709419-20180809232059588-357061454.png

二、模型定义

1、基本的模型

1 from django.db importmodels2

3

4 classBookInfo(models.Model):5 """

6 图书类 => 图书表(booktest_bookinfo)7 """

8 #图书标题 => varchar(20)

9 btitle = models.CharField(max_length=20)10 #发布日期 => datetime

11 bpub_date =models.DateTimeField()12 #阅读数 => int(11)

13 bread = models.IntegerField(default=0)14 #评论数 => int(11)

15 bcomment = models.IntegerField(default=0)16 #是否删除 => tinyint

17 isDelete = models.BooleanField(default=False)18

19 def __str__(self):20 returnself.btitle21

22

23 classHeroInfo(models.Model):24 """

25 英雄类 => 英雄表(booktest_heroinfo)26 """

27 #英雄名字 => varchar(20)

28 hname = models.CharField(max_length=20)29 #性别 => tinyint

30 hgender = models.BooleanField(default=True)31 #简介 => varchar(1000)

32 hcontent = models.CharField(max_length=1000)33 #是否删除 => tinyint

34 isDelete = models.BooleanField(default=False)35 #外键 => int(11)

36 hbook = models.ForeignKey(BookInfo) #外键

说明:

定义属性时,需要字段类型

字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中

使用方式:见上面代码

对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False

2、字段类型(引用)

表单控制是指在django管理站点的前端显示。

AutoField:根据ID自动增长的IntegerField,一般无需指定,django会自动添加到模型中,数据库类型为 int(11)。

BooleanFidld:true/false字段,此字段的默认表单控件是CheckboxInput,数据库类型为 tinyint。

NullBooleanField:支持null、true、false三种值,数据库类型为 tinyint。

CharField(max_length=字符长度):字符串,默认的表单控件是TextInput,数据库类型为 varchar(字符长度)。

TextField:大文本字段,一般字符长度超过4k使用,默认的表单控件是Textarea,数据库类型为 varchar(字符长度)。

IntegerField:整数,数据库类型为 int。

DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数,数据库类型为 decimal(P, D):

DecimalField.max_digits:位数总数

DecimalField.decimal_places:小数点后的数字位数。

FloatField:使用python的float实例来标识的浮点数。

DateField([auto_now=False, auto_noew_add=False]):使用pyhton的datetime.date实例表示日期。

参数auto_now:每次保存对象时,自动设置该字段为当前时间,用于保存"最后一次修改"的时间戳,他总是使用当前的日期,默认为false

参数auto_now_add:当对象第一次被创建时自动设置当前时间,用于保存创建的时间戳,它总是使用当前日期,默认为false

该字段默认对应的表单控件是TextInput

auto_now、auto_now_add、default 这些设置是相互排斥的,他们之间任何组合将会发生错误的结果 。

TimeField:使用python的datetime.time实例表示的时间,参数同DatEField。

DateTimeField:使用python的datetime.datetime实例表示的日期和时间,参数同DateField

FileField:一个上传文件的字段,一般不会把文件保存在数据库中,建议保存文件上传的路径。

ImageField:继承FieldField的所有属性和方法,当对上传的对象进行校验,确保上传是有些的image。

3、字段选项

使用:title = models.CharFidle(null=True)

null:如果为True,Django将空值以NULL存储到数据库中,默认值是False。

blank:如果为True,则该字段允许为空,默认值是False。

null与blank对比:null是数据库范畴的概念,blank是表单验证范畴的。

db_column:字段的名称,如果为指定,则使用属性的名称。

db_index:如果为True,则在表中会为此字段创建索引

default:默认值。

primary_key:如果为True,则该字段会成为模型的主键字段。

unique:如果为True,表示这个字段在表中必须有唯一值。

4、关系

关系的类型有如下:

ForeignKey:一对多,将字段定义在多的端中(如上面基本模型的代码)。

ManyToManyField:多对多,将字段定义在两端中。

OneToOneField:一对一,将字段定义在任意一端中。

访问方式:

用一访问多:对象.模型类小写_set

bookinfo.heroinfo_set

用一访问一:对象.模型类小写

heroinfo.bookinfo

heroinfo.book_id

5、元选项

在模型类中定义类Meta,用于设置元信息

1 classBookInfo(models.Model):2 #元选项

3 classMeta:4 #数据表名

5 db_table = 'bookinfo'

6 #对象默认排序字段,正序

7 ordering = ['id']8 #ordering = ['-id'] # 倒序

三、模型成员

1、查询数据

book_list = BookInfo.objects.all()

2、Django默认的管理器

objects:是Manager类型的对象,用于与数据库进行交互。

当定义模型时没有指定管理器,则Django会为模型类提供一个名为objects的管理器。

支持明确指定管理器(如果自己指定manager,django不再为模型类生成名为objects的默认管理器):

1 classBookInfo(models.Model):2 manager1 = models.Manager()

3、自定义管理器

管理器是Django的模型进行数据库的查询操作的接口,Django应用的每个模型都拥有至少一个管理器。

自定义管理器主要用于以下两种情况:

情况一:修改管理器返回的原始查询集:重写get_query_set()方法。

情况二:向管理器中添加额外的方法

代码如下(manager2就是自定义的管理器):

1 classBookInfoManager(models.Manager):2 """

3 自定义管理器4 """

5 #情况一:更改默认查询结果,只查未删除的数据

6 defget_queryset(self):7 return super(BookInfoManager, self).get_queryset().filter(isDelete=False)8

9 #情况二:定义模型类的创建方法

10 defcreate(cls, btitle, bpub_date):11 b =BookInfo()12 b.btitle =btitle13 b.bpub_date =bpub_date14 b.bread =015 b.bcomment =016 b.isDelete =False17 returnb18

19

20 classBookInfo(models.Model):21 btitle = models.CharField(max_length=20)22 bpub_date =models.DateTimeField()23 bread = models.IntegerField(default=0)24 bcomment = models.IntegerField(default=0)25 isDelete = models.BooleanField(default=False)26

27 def __str__(self):28 returnself.btitle29

30 #管理器

31 manager1 =models.Manager()32 manager2 = BookInfoManager()

情况一的测试结果如下:

709419-20180810103518596-1497361281.png

709419-20180810103527956-1355111508.png

情况二的测试结果如下(简化创建对象的过程:new->赋值->save):

709419-20180810103751207-399321170.png

709419-20180810103802228-1919674287.png

四、模型查询

1、查询集

在管理器上调用过滤器方法返回查询集。

查询集经过过滤筛选后返回信的查询集,因此可以写成链式过滤。

惰性执行:创建查询集不会带来任何数据的访问,直到调用数据的时候(迭代、序列号、与if合用),才会访问数据库。

返回查询集的方法,称为过滤器:all()、filter()、exclude()、order_by()、values()

写法:manager.filter(键1=值1, 键2=值2) => manager.filter(键1=值1).filter(键2=值2)

709419-20180810105252063-473176513.png

返回单个值的方法:

get():返回单个满足添加的对象

如果未找到会引发"模型类 DoesNotExist"异常

如果多条被返回,会引发"模型类 MultipleObjectsReturn"异常

count():返回当前查询的总条数

first():返回第一个对象

last():返回最后一个对象

exists():判断查询集中是否有数据,有则返回True

限制查询集:

查询集返回列表,可以使用下标的方式进行限制,等同于sql中limit和offset子句

注意:不支持负数索引

如果下标返回一个新的查询集,不会立刻执行查询

如果获取一个对象,直接使用[0],等同于[0:1].get()。但是如果没有数据,[0]引发IndexError异常,[0:1].get()引发DoesNotExist异常。

查询集的缓存

每个查询集都包含一个缓存来最小化对数据库的访问。

在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,Django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存的结果。

情况一:构建两个查询集,无法重用缓存,每次查询都会与数据库进行交互,增加数据库的负载

709419-20180810105915300-23858849.png

情况二:两次循环使用同一个查询集,第二次使用缓存中的数据

709419-20180810110059285-1459157122.png

何时查询集不会被缓存:当只对查询集的部分进行求值时,会检查缓存,但是如果这部分不再缓存中,那么接下来查询返回的几率将不会被缓存,这意味着使用索引来限制查询集将不会填充缓存,如果这部分数据已经被缓存,则直接使用缓存中的数据。

1 query =BookInfo.objects.all()2 for each in query #缓存

3 for each in query[0,10] #不缓存

4 #使用子集不缓存

2、字段查询:比较运算符,F对象,Q对象

实现where子句,作为方法filter()、exclude()、get()的参数。

语法:属性名__比较运算符=值,__ 表示两个下划线,左侧是属性名称,右侧是比较类型。

对于外键:使用 "属性名__id" 表示外键原始值

转义:like语句中使用%与_,匹配数据中的%与_,在过滤器中直接写:

filter(title__contains="%") => WHERE `title` LIKE '%\%%'

比较运算符

exact:表示判等,大小写敏感,如果没有写 “比较运算符”,表示判等:

filter(isDelete=False) => WHERE `isDelete` = 0

contains:是否包含。大小写敏感:

exclude(btitle__contains='传') => WHERE `btitle` LIKE '%传%'

startswhit、endswith:以value开头或结尾,大小写敏感:

exclude(btitle__endswith='传') => WHERE `btitle` LIKE '%传'

exclude(btitle__startswith='传') => WHERE `btitle` LIKE '传%'

isnull、isnotnull:是否为null:

filter(btitle__isnull=False) => WHERE `btitle` != null

在前面加 i 表示不区分大小写,如:iexact、icontains、istartswith、iendswith

in:是否包含在范围内:

filter(pk__in=[1,2,3]) => WHERE `id` IN (1, 2, 3)

gt、gte、lt、lte:大于、大于等于、小于、小于等于

filter(id__gt=3) => WHERE `id` > 3

filter(id__lte=5) => WHERE `id` <= 5

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算:

filter(bpub_date__year=1980)

filter(bpub_date__gt=date(1980, 12, 31))

跨关系的查询:处理join查询:

filter(heroinfo__hcontent__contains='八') => SELECT * FROM `bookinfo` JOIN `heroinfo` ON `bookinfo`.`id`=`heroinfo`.`hbook` WHERE `heroinfo`.`hcontent` LIKE '%八%'

聚合函数:

使用aggregate()函数返回聚合函数的值

函数:Avg、Count、Max、Min、Sum

from django.db.models importMax

maxDate= BookInfo.objects.aggregate(Max('bpub_date'))

count的一般用法:count = list.count()

F对象:构建等号右侧字段:

可以使用模型的字段A与字段B进行比较,如果A在等号左侧,则B出现在等号的右侧时需要通过F对象构造:

list.filter(bread__gt=F('bcomment')) => WHERE `bread` > `bcomment`

Django支持对F对象使用算数运算:

list.filter(bread__gte=F('bcomment')) => WHERE `bread` >= `bcomment` * 3

F()对象还可以写作“模型类__列名”进行关联查询:

list.filter(isDelete=F('heroinfo__isDelete')) => WHERE `bookinfo`.`isDelete` = `heroinfo`.`isDelete`

对于date/time字段,可与timedelta()进行运算:

list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))

Q对象:处理逻辑或:

过滤器方法中关键字参数查询,会合并为And进行查询。

需要进行or查询,使用Q对象

Q对象(django.db.models.Q)用于封装一组关键字参数,这些关键字参数与“比较运算符”中的相同

from django.db.models importQ

list.filter(Q(pk__lt=6))

Q对象可以使用&(and)、|(or)操作符组合起来

当操作符应用在两个Q对象时,会产生一个新的Q对象

list.filter(pk__lt=6).filter(bcomment__gt=10) # WHERE `id` < 6 AND `bcomment` > 10

list.filter(Q(pk__lt=6) | Q(bcomment__gt=10))  # WHERE `id` < 6 OR `bcomment` > 10

使用~(not)操作符在Q对象前表示取反

list.filter(~Q(pk__lt=6))

可以使用&|~结合括号进行分组,构造复杂的Q对象

过滤函数可以传递一个或多个Q对象作为位置参数,如果有多个Q对象,这些参数的逻辑为and

过滤器函数可以混合使用Q对象和关键字参数,所有参数都将And在一起,Q对象必须位于关键字参数的前面。

五、自连接

自连接主要应用于无限级分类等。

1 classAreaInfo(models.Model):2 atitle = models.CharFields(max_lenth=20)3 aParent = mdoels.ForeignKey('self', null=True, blank=True)

访问关联对象:

上级:area.aParent

下级:area.areainfo_set.all()

附录一:使用mysql数据库

1、安装插件:python-mysql 或 mysqlclient

我的电脑安装的是python3.5,通过wheel安装mysqlclient,下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient

2、修改配置文件

709419-20180810135936674-399294822.png

附录二:Django开发流程

1、创建项目:执行指令:django-admin startproject [项目名]

2、进入项目目录,创建应用:执行指令:python manager.py startapp [应用名]

3、进入应用目录,在models.py中定义模型类,要求继承自models.Model

4、把应用加入settings.py文件中的installed_app项中

5、生成迁移文件,执行指令:python manager.py makemigrations

6、执行迁移生成表,执行指令:python manager.py migrate

7、使用模型类进行crud操作

*、使用数据库生成模型类

python manager.py inspectdb > booktest/models.py

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值