day 035 Model

今天继续Django的学习,今天是Model,模型部分
- model 是指MVT模式中的M部分,就是Django框架中跟数据库交互数据的部分
- 在Django中,Model是遵循ORM的

这里写图片描述

  • Model模块包括ORM的好处:
    • 实现了数据模型与数据库的解耦,通过简单的配置就可以轻松的更换数据库而不需要修改代码
    • 只需要面向对象编程,不需要面向数据库编写代码
    • 在MVC中Model中定义的类,通过ORM与关系型数据库中的表对应,对象的属性体现对象间的关系,这种关系也被映射到数据表中

修改配置文件,使用MySQLS数据库

  • 将引擎改为mysql,提供连接的主机HOST、端口PORT、数据库名NAME、用户名USER、密码PASSWORD
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test2', #数据库名字,
        'USER': 'root', #数据库登录用户名
        'PASSWORD': 'mysql', #数据库登录密码
        'HOST': 'localhost', #数据库所在主机
        'PORT': '3306', #数据库端口
    }
}

属性类型及选项

  • Django属性的类型对用数据库中字段的类型

属性命名限制

  • 不能事Python的保留关键字
  • 不允许使用联系的下划线
  • 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下

属性=models.字段类型(选项)

字段类型

  • AutoField:自动增长的integerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
  • BooleanField:支持Null,True,False三种值
  • CharField(max_length=字符长度):字符串
    • 参数max_length表示最大字符个数,字符串中必须指定
  • TextField:大文本字段,一般超过4000个字符时使用
  • IntergerField:整数
  • DecimalField(max_digits=None,decimal_place=None):十进制浮点数
    • 参数max_digits表示总位数,必须指定
    • 参数decimal_places表示小数位数,必须指定
  • FloatField:浮点数
  • DateField(auto_now=False,auto_now_add=False):日期
    • 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于‘最后一次修改’的时间戳,它总是使用当前日期,默认为false
    • 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,他总是使用当前日期,默认为false
    • 参数auto_now_add和auto_now是互相排斥的,同时只能有一个设置为true
  • TimeField:时间,参数同DateField
  • DateTimeField:日期时间,参数同DateField
  • FileField:上传文件字段
  • ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片

选项

选项即为数据库中字段的约束
- null:如果为True,表示允许为空,默认值是False
- blank:如果为True,则该字段允许为空白,默认值是False
- 注意null和blank:null是可以在数据表存为null,blank是admin里表单提交时会做验证,如果blank是true才可以提交空白字符串
- db_column:字段的名称,如果未指定,则使用属性的名称
- db_index:若值为True,则在表中会为此字段创建索引,默认值是False
- default:默认值
- primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
- unique:如果为True,这个字段在表中必须有唯一值,默认值是False

条件查询和查询集

  • 实现SQL中的where的功能,调用过滤器filter(),exclude(),get()
  • 常用的运算符如下

    • exact:表示判等
    • contains:是否包含
    • startwith,endwith:以指定值开头或者结尾
    • isnull:是否为null
    • in:是都包含在范围内
    • gt,gte,lt,lte:>,>=,<,<=
    • excude():不等于某个值
    • year,month,day,week_day,hour,minute,second:对日期时间类型的属性进行运算
    • F对象, Q对象

    • 语法如下:

    属性名称__比较运算符=值

条件运算符

  • exact:表示判等
 例:查询编号为1的图书。

list=BookInfo.objects.filter(id__exact=1)

可简写为:

list=BookInfo.objects.filter(id=1)
  • contains:是否包含
例:查询书名包含'湖'的图书。

list = BookInfo.objects.filter(btitle__contains='湖')
  • startswith、endswith:以指定值开头或结尾
例:查询书名以'部'结尾的图书

list = BookInfo.objects.filter(btitle__endswith='部')
  • isnull:是否为null
例:查询书名不为空的图书。

list = BookInfo.objects.filter(btitle__isnull=False)
  • gt、gte、lt、lte:大于、大于等于、小于、小于等于
例:查询编号大于3的图书

list = BookInfo.objects.filter(id__gt=3)

  • 不等于的运算符,使用exclude()过滤器
例:查询编号不等于3的图书

list = BookInfo.objects.exclude(id=3)
  • year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算
例:查询1980年发表的图书。

list = BookInfo.objects.filter(bpub_date__year=1980)
例:查询198011日后发表的图书。

list = BookInfo.objects.filter(bpub_date__gt=date(1980, 1, 1))
  • 之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中。
语法如下:

F(属性名)
例:查询阅读量大于等于评论量的图书。

from django.db.models import F
...
list = BookInfo.objects.filter(bread__gte=F('bcomment'))
  • 多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字 –Q对象
例:查询阅读量大于20,并且编号小于3的图书。

list=BookInfo.objects.filter(bread__gt=20,id__lt=3)
或
list=BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)
如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符,Q对象被义在django.db.models中。

语法如下:

Q(属性名__运算符=值)
例:查询阅读量大于20的图书,改写为Q对象如下。

from django.db.models import Q
...
list = BookInfo.objects.filter(Q(bread__gt=20))
Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。
例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现

list = BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))
Q对象前可以使用~操作符,表示非not。
例:查询编号不等于3的图书。

list = BookInfo.objects.filter(~Q(pk=3))
如果是逻辑与&的实现,可以不用Q对象,用Q反而麻烦了

聚合函数

  • Avg(平均数),Count(计数),Max(最大值),Min(最小值),Sum(计算和)
例:查询图书的总阅读量。

from django.db.models import Sum
...
list = BookInfo.objects.aggregate(Sum('bread'))
注意aggregate的返回值是一个字典类型,格式如下:
  {'属性名__聚合类小写':值}
  如:{'bread__sum':3}
使用count时一般不使用aggregate()过滤器。

例:查询图书总数。

list = BookInfo.objects.count()
注意count函数的返回值是一个数字。

查询集

  • 表示从数据库中获取的对象集合

  • 返回查询集的过滤器如下:

    • all():返回所有数据。
    • filter():返回满足条件的数据。
    • exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字。
    • order_by():对结果进行排序。比如order_by(‘num’),如果逆序:order_by(‘-num’)
  • 返回单个值的过滤器如下:
    • get():返回单个满足条件的对象
    • 如果未找到会引发”模型类.DoesNotExist”异常。
    • 如果多条被返回,会引发”模型类.MultipleObjectsReturned”异常。
    • count():返回当前查询结果的总条数。
    • aggregate():聚合,返回一个字典。
  • 判断某一个查询集中是否有数据:

    • exists():判断查询集中是否有数据,如果有则返回True,没有则返回False。
  • 两大特性

    • 惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。
    • 缓存:使用同一个查询集,第一次使用时会发生数据库的查询,然后把结果缓存下来,再次使用这个查询集时会使用缓存的数据。

模型类关联

  • 关系型数据库的关系包括三种类型:
    • ForeignKey:一对多,将字段定义在多的一端中。
    • ManyToManyField:多对多,将字段定义在任意一端中。
    • OneToOneField:一对一,将字段定义在任意一端中。
  • 可以维护递归的关联关系,使用’self’指定。

关联查询

通过对象执行关联查询

  • 由一到多的访问:
例:图书和英雄是一对多的关系,已经有图书对象b,那么想获取b里的所有英雄就需要b.heroinfo_set.all(), heroinfo是英雄类名的小写后面加上 _set

b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()

注意如上代码中heroinfo_set并不是我们在类的定义的是django为我们生成好的

例:图书和英雄是一对多的关系,已经有图书对象b,那么想获取b里的所有英雄就需要b.heroinfo_set.all(), heroinfo是英雄类名的小写后面加上 _set
b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()

注意如上代码中heroinfo_set并不是我们在类的定义的是django为我们生成好的
  • 由多到一的访问语法:
图书和英雄是一对多的关系,那么关联的部分是写到了英雄类里叫hbook,参考HeroInfo类里的写法, 现在有英雄对象h,如果想获取英雄所属于的图书,直接调用hbook就好: h.hbook
    h = HeroInfo.objects.get(id=1)
    h.hbook

在一对多中,比如图书和英雄,已有英雄对象h,可以获取到所属英雄的id如下.
    多对应的模型类对象.关联类属性_id
例:
h = HeroInfo.objects.get(id=1)
h.book_id

注意如上代码中book_id并不是我们在类的定义的是django为我们生成好的

通过模型类执行关联查询

  • 由多模型类条件查询一模型类数据:
语法如下:
关联模型类名小写__属性名__条件运算符=值

如果没有"__运算符"部分,表示等于,结果和sql中的inner join相同。

例:查询图书,要求图书中英雄的描述包含'八'。
list = BookInfo.objects.filter(heroinfo__hcontent__contains='八')
  • 由一模型类条件查询多模型类数据:
语法如下:
模型类关联属性名__一模型类属性名__条件运算符=值

例:查询书名为“天龙八部”的所有英雄。
list = HeroInfo.objects.filter(hbook__btitle='天龙八部') 

自关联

  • 对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以设计成一张表,内部的关系字段指向本表的主键,这就是自关联的表结构

自定义管理器及用途

  • 管理器是Django的模型进行数据库操作的接口,Django应用的每个模型类都拥有至少一个管理器
  • Django支持自定义管理器类,继承自models.Manage
  • 一般自定义管理器类主要用于两种情况:
    • 修改原始查询集,重写get_queryset()方法
    • 向管理器类中添加额外的方法,如向数据库中插入数据。

元选项

  • 在模型类中定义类Meta,用于设置元信息,如使用db_table自定义表的名字

    “`
    例:指定BookInfo模型类生成的数据表名为bookinfo。
    在BookInfo模型类中添加如下内容,代码如下:

定义图书模型类BookInfo

class BookInfo(models.Model):

定义元选项

class Meta:
db_table=’bookinfo’ #指定BookInfo生成的数据表名为bookinfo
“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>