说明:

  本文主要深入了解模型(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中的模型包含存储的字段和约束,对应着数据库中唯一的表。

  

二、模型定义

  1、基本的模型  

 from django.db import models

 class BookInfo(models.Model):
"""
图书类 => 图书表(booktest_bookinfo)
"""
# 图书标题 => varchar(20)
btitle = models.CharField(max_length=20)
# 发布日期 => datetime
bpub_date = models.DateTimeField()
# 阅读数 => int(11)
bread = models.IntegerField(default=0)
# 评论数 => int(11)
bcomment = models.IntegerField(default=0)
# 是否删除 => tinyint
isDelete = models.BooleanField(default=False) def __str__(self):
return self.btitle class HeroInfo(models.Model):
"""
英雄类 => 英雄表(booktest_heroinfo)
"""
# 英雄名字 => varchar(20)
hname = models.CharField(max_length=20)
# 性别 => tinyint
hgender = models.BooleanField(default=True)
# 简介 => varchar(1000)
hcontent = models.CharField(max_length=1000)
# 是否删除 => tinyint
isDelete = models.BooleanField(default=False)
# 外键 => int(11)
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,用于设置元信息    

 class BookInfo(models.Model):
# 元选项
class Meta:
# 数据表名
db_table = 'bookinfo'
# 对象默认排序字段,正序
ordering = ['id']
# ordering = ['-id'] # 倒序

三、模型成员

  1、查询数据

     book_list = BookInfo.objects.all()

  

  2、Django默认的管理器

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

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

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

 class BookInfo(models.Model):
manager1 = models.Manager()

  3、自定义管理器

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

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

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

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

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

 class BookInfoManager(models.Manager):
"""
自定义管理器
"""
# 情况一:更改默认查询结果,只查未删除的数据
def get_queryset(self):
return super(BookInfoManager, self).get_queryset().filter(isDelete=False) # 情况二:定义模型类的创建方法
def create(cls, btitle, bpub_date):
b = BookInfo()
b.btitle = btitle
b.bpub_date = bpub_date
b.bread = 0
b.bcomment = 0
b.isDelete = False
return b class BookInfo(models.Model):
btitle = models.CharField(max_length=20)
bpub_date = models.DateTimeField()
bread = models.IntegerField(default=0)
bcomment = models.IntegerField(default=0)
isDelete = models.BooleanField(default=False) def __str__(self):
return self.btitle # 管理器
manager1 = models.Manager()
manager2 = BookInfoManager()

    情况一的测试结果如下:

      

        

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

      

        

四、模型查询

  1、查询集

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

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

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

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

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

      

    返回单个值的方法:

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

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

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

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

      first():返回第一个对象

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

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

    

    限制查询集:

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

      注意:不支持负数索引

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

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

      

    查询集的缓存

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

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

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

      

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

        

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

 query = BookInfo.objects.all()
for each in query # 缓存
for each in query[0,10] # 不缓存
# 使用子集不缓存

  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 import Max
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 import Q
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对象必须位于关键字参数的前面。

五、自连接

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

 class AreaInfo(models.Model):
atitle = models.CharFields(max_lenth=20)
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、修改配置文件

      

 附录二: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

[Python] Django框架入门2——深入模型的更多相关文章

  1. [Python] Django框架入门

    说明:Django框架入门 当前项目环境:python3.5.django-1.11 项目名:test1 应用名:booktest 命令可简写为:python manager.py xxx => ...

  2. [Python] Django框架入门5——静态文件、中间件、上传图片和分页

    说明: 本文主要描述Django其他的内容,涉及静态文件处理.中间件.上传文件.分页等. 开发环境:win10.Python3.5.Django1.10. 一.静态文件处理 在Django项目的静态文 ...

  3. [Python] Django框架入门3——深入视图

    说明: 本文主要深入了解视图(views.py),涉及路由配置.定义视图.Request对象.Response对象.状态保持等. 一.路由配置 1.配置位置(settings.py 的 ROOT_UR ...

  4. [Python] Django框架入门4——深入模板

    说明: 本文主要深入了解模板(templates),主要涉及模板编写步骤.定义模板.模板继承.HTML转义.CSRF等. 一.模板 动态生成HTML.表达外观.实现业务逻辑(view)与显示内容(te ...

  5. Django框架 之 ORM中介模型

    Django框架 之 ORM中介模型 中介模型 处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField  就可以了.但是,有时你可能需要关联数据 ...

  6. 利用 Python django 框架 输入汉字,数字,字符,等。。转成二维码!

    利用 Python django 框架 输入汉字,数字,字符,等..转成二维码! 模块必备:Python环境 + pillow  + qrcode 模块 核心代码import qrcode qr = ...

  7. Python Django框架笔记(五):模型

    #前言部分来自Django Book (一)    前言 大多数web应用本质上: 1. 每个页面都是将数据库的数据以HTML格式进行展现. 2. 向用户提供修改数据库数据的方法.(例如:注册.发表评 ...

  8. Python Django框架笔记(三):django工作方式简单说明和创建用户界面

    (一)  说明 简单说明下django的工作方式,并举2个例子. (二)  Django工作方式 假定我们有下面这些文件 ,这里在前2篇的基础上增加了 templates目录(存放html文件) 和s ...

  9. Python Django框架笔记(一):安装及创建项目

     #推荐一本书<Python核心编程>(适合有一定基础的),美国人Wesley Chun编写的,京东.淘宝应该都有.我是觉得写的很好,详细.简洁.满满的干货,不像有的书整本看完也没什么用. ...

随机推荐

  1. vue教程(一)-html使用vue

    前后端分离.微服务框架是当下比较流行的词汇,而vue就是前端框架的佼佼者.下面重点介绍一下vue的用法: vue起步:1.引包    2.启动new Vue({el:目的地,template:模板内容 ...

  2. CHM格式

    转载请标明出处:https://www.cnblogs.com/tangZH/p/11176995.html CHM格式为CHM头,CHM头节,内容三部分组成. 总体格式图: 初始化头包含了CHM的相 ...

  3. Java_异常介绍

    今日内容介绍: 掌握异常概述 理解异常的基础操作以及最简单的捕获处理 理解多异常捕获处理 理解声明抛出异常 掌握自定义异常 掌握异常处理注意事项 异常 什么是异常?Java代码在运行时期发生的问题就是 ...

  4. Linux基础之特殊权限

    22.5)特殊权限 22.5.1)SetUID(简称suid)(数字权限是4000) 命令功能: 临时使用命令的属主权限执行该命令.即如果文件有suid权限时,那么普通用户去执行该文件时,会以该文件的 ...

  5. HTML&CSS兼容性总结

    对目前所遇见的兼容性笔记进行整理分类: 不兼容浏览器 问题概要 问题描述 解决方法 IE6,IE7  3px 并列一行的元素左侧第一个元素没浮动,第二个元素左浮动,则两个元素之间会多3像素空隙 并在一 ...

  6. [原创]一款基于Reactor线程模型的java网络爬虫框架

    AJSprider 概述 AJSprider是笔者基于Reactor线程模式+Jsoup+HttpClient封装的一款轻量级java多线程网络爬虫框架,简单上手,小白也能玩爬虫, 使用本框架,只需要 ...

  7. 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!

    1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...

  8. 腾讯位置服务API快速入门

    前言 之前项目有个需求,在网页上显示微信发送过来的位置信息,该开始想用百度地图,后来发现腾讯地图相对简单一点 快速入门 申请Key https://lbs.qq.com/guides/startup. ...

  9. Kafka服务不可用(宕机)问题踩坑记

    背景 某线上日志收集服务报警,打开域名报502错误码. 收集服务由2台netty HA服务器组成,netty服务器将客户端投递来的protobuf日志解析并发送到kafka,打开其中一个应用的日志,发 ...

  10. FormLayout and FormData

    FormLayout通过为小窗口部件创建四边的Form附加值(attachment)来进行工作,并且把这些Form附加值存储在布局数据中.一个附加值让一个小窗口部件指定的一边粘贴(attach)到父C ...