ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

后端>>Django的模型M

2019-08-23 12:38:38  阅读:236  来源: 互联网

标签:__ Django models 模型 BookInfo objects 查询 id


Django ORM

  • O(objects):类和对象。
  • R(Relation):关系,关系数据库中的表格。
  • M(Mapping):映射。在这里插入图片描述
    Django ORM框架的功能:
    • a) 建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
    • b) 根据设计的模型类生成数据库中的表格。
    • c) 通过方便的配置就可以进行数据库的切换。


Django数据库配置

  1. 首先需要安装 pymysql
    pip install pymysql

  2. 然后 在test2底下的test2添加以下内容
    添加了该内容后才可以启动django的服务器在这里插入图片描述
    添加了该内容后才可以启动django的服务器

  3. 修改settings.py中的DATABASES。
    在这里插入图片描述



定义属性

参考文档
http://python.usyiyi.cn/translate/django_182/index.html

属性命名限制:

  • 不能是python的保留关键字。
  • 不允许使用连续的下划线,这是由django的查询方式决定的,在第4节会详细讲解查询。
  • 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
    属性=models.字段类型(选项)
1.字段类型

使用时需要引入django.db.models

字段类型 使用方法/解释 是否常用
AutoField 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField 布尔字段,值为True或False
NullBooleanField 支持Null、True、False三种值
CharField(max_length=字符长度) 字符串。
参数max_length表示最大字符个数
TextField 大文本字段,一般超过4000个字符时使用
IntegerField 整数
DecimalField(max_digits=None, decimal_places=None) 十进制浮点数
* 参数max_digits表示总位数
* 参数decimal_places表示小数位数
FloatField 浮点数
DateField[auto_now=False, auto_now_add=False]) 日期
**DateField[auto_now=False, auto_now_add=False]) 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
*DateField[auto_now=False, auto_now_add=False]) 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
*DateField[auto_now=False, auto_now_add=False]) 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField 时间,参数同上面三个
DateTimeField 日期时间, 参数同上上面三个
FileField 上传文件字段
ImageField 继承于FileField,对上传的内容进行校验,确保是有效的图片
2. 选项

通过选项实现对字段的约束,选项如下:

选项类型 使用方法/解释 是否常用
default 默认值。设置默认值。
primary_key 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。
unique 如果为True, 这个字段在表中必须有唯一值,默认值是False
db_index 若值为True, 则在表中会为此字段创建索引,默认值是False
db_column 字段的名称,如果未指定,则使用属性的名称
null 如果为True,表示允许为空,默认值是False
blank 如果为True,则该字段允许为空白,默认值是False

对比:null是数据库范畴的概念,blank是后台管理页面表单验证范畴的。

经验:
当修改模型类之后,如果添加的选项不影响表的结构,则不需要重新做迁移,商品的选项中default和blank不影响表结构。

演示代码
from django.db import models

#定义图书模型类BookInfo
class BookInfo(models.Model):
    #btitle = models.CharField(max_length=20)#图书名称
    btitle = models.CharField(max_length=20, db_column='title')#通过db_column指定btitle对应表格中字段的名字为title
    bpub_date = models.DateField()#发布日期
    bread = models.IntegerField(default=0)#阅读量
    bcomment = models.IntegerField(default=0)#评论量
    isDelete = models.BooleanField(default=False)#逻辑删除

#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
    hname = models.CharField(max_length=20)#英雄姓名
    hgender = models.BooleanField(default=True)#英雄性别
    isDelete = models.BooleanField(default=False)#逻辑删除
    #hcomment = models.CharField(max_length=200)#英雄描述信息
    hcomment = models.CharField(max_length=200, null=True, blank=False) #hcomment对应的数据库中的字段可以为空,但通过后台管理页面添加英雄信息时hcomment对应的输入框不能为空
    hbook = models.ForeignKey('BookInfo')#英雄与图书表的关系为一对多,所以属性定义在英雄模型类中


字段查询

实现sql中where的功能,调用过滤器filter()exclude()get(),下面以filter()为例。

通过"属性名_id"表示外键对应对象的id值。

语法如下:
注意:属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线。

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

查询函数

通过模型类.objects属性可以调用如下函数

函数名 功能 返回值 说明
get 返回表中满足条件的一条且只能有一条数据。 返回值是一个模型类对象。 参数中写查询条件。
1) 如果查到多条数据,则抛异常MultipleObjectsReturned。
2)查询不到数据,则抛异常:DoesNotExist。
all 返回模型类对应表格中的所有数据。 返回值是QuerySet类型 查询集
filter 返回满足条件的数据。 返回值是QuerySet类型 参数写查询条件。
exclude 返回不满足条件的数据。 返回值是QuerySet类型 参数写查询条件。
order_by 对查询结果进行排序。 返回值是QuerySet类型 参数中写根据哪些字段进行排序。
案例
get示例:
例:查询图书id为3的图书信息。

all方法示例:
例:查询图书所有信息。

filter方法示例:
条件格式:模型类属性名__条件名=值
查询图书评论量为34的图书的信息:

a)判等 条件名:exact。
	例:查询编号为1的图书。
	BookInfo.objects.get(id=1)

b)模糊查询
	例:查询书名包含'传'的图书。contains
	BookInfo.objects.filter(btitle__contains='传')
	例:查询书名以'部'结尾的图书 endswith 开头:startswith
	BookInfo.objects.filter(btitle__endswith='部')

c)空查询 isnull
	例:查询书名不为空的图书。isnull 
	select * from booktest_bookinfo where btitle is not null;
	BookInfo.objects.filter(btitle__isnull=False)

d)范围查询 in
	例:查询id为1或3或5的图书。
	select * from booktest_bookinfo where id in (1,3,5);
	BookInfo.objects.filter(id__in = [1,3,5])

e)比较查询 
gt(greate than) 大于 
lt(less  than)  小于 
gte(equal) 大于等于
lte 小于等于

	例:查询id大于3的图书。
	Select * from booktest_bookinfo where id>3;
	BookInfo.objects.filter(id__gt=3)

f)日期查询
	例:查询1980年发表的图书。
	BookInfo.objects.filter(bpub_date__year=1980)
	
	例:查询1980年1月1日后发表的图书。
	from datetime import date
	BookInfo.objects.filter(bpub_date__gt=date(1980,1,1))
	
exclude方法示例:
	例:查询id不为3的图书信息。
	BookInfo.objects.exclude(id=3)
	
order_by方法示例:
	作用:进行查询结果进行排序。
	
	例:查询所有图书的信息,按照id从小到大进行排序。
	BookInfo.objects.all().order_by('id')
	
	例:查询所有图书的信息,按照id从大到小进行排序。
	BookInfo.objects.all().order_by('-id')
	
	例:把id大于3的图书信息按阅读量从大到小排序显示。
	BookInfo.objects.filter(id__gt=3).order_by('-bread')

F对象

作用:用于类属性之间的比较。
F(属性名)

使用之前需要先导入:
from django.db.models import F

例:查询图书阅读量大于评论量图书信息。
BookInfo.objects.filter(bread__gt=F('bcomment'))

例:查询图书阅读量大于2倍评论量图书信息。
BookInfo.objects.filter(bread__gt=F('bcomment')*2)

Q对象

作用:用于查询时条件之间的逻辑关系。not and or,可以对Q对象进行&|~操作。
Q(属性名__运算符=值)

&表示逻辑与,|表示逻辑或, ~操作符,表示非not。

使用之前需要先导入:
from django.db.models import Q

例:查询id大于3且阅读量大于30的图书的信息。
BookInfo.objects.filter(id__gt=3, bread__gt=30)
BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))

例:查询id大于3或者阅读量大于30的图书的信息。
BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))

例:查询id不等于3图书的信息。
BookInfo.objects.filter(~Q(id=3))


聚合函数

  • 作用:对查询结果进行聚合操作。

  • 使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中。

  • 使用前需先导入聚合类:

    from django.db.models import Sum,Count,Max,Min,Avg

  • aggregate
    • 调用这个函数来使用聚合。 返回值是一个字典
      例:查询所有图书的数目。
      BookInfo.objects.all().aggregate(Count('id'))
      {'id__count': 5}
      例:查询所有图书阅读量的总和。
      BookInfo.objects.aggregate(Sum('bread'))
      {'bread__sum': 126}
      
  • count函数
    • 返回值是一个数字
    • 作用:统计满足条件数据的数目。
      例:统计所有图书的数目。
      BookInfo.objects.all().count()
      BookInfo.objects.count()
      例:统计id大于3的所有图书的数目。
      BookInfo.objects.filter(id__gt=3).count()
      
小结

参考文档:
http://python.usyiyi.cn/translate/django_182/ref/models/querysets.html

在这里插入图片描述



查询级

  • 查询集表示从数据库中获取的对象集合,在管理器上调用某些过滤器方法会返回查询集,查询集可以含有零个、一个或多个过滤器。过滤器基于所给的参数限制查询的结果,从Sql的角度,查询集和select语句等价,过滤器像where和limit子句。

  • all, filter, exclude, order_by调用这些函数会产生一个查询集,QuerySet类对象可以继续调用上面的所有函数。

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

    all():返回所有数据。
    filter():返回满足条件的数据。
    exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字。
    order_by():对结果进行排序。

  • 返回单个值的过滤器如下:

    get():返回单个满足条件的对象
    如果未找到会引发"模型类.DoesNotExist"异常。
    如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常。
    count():返回当前查询结果的总条数。
    aggregate():聚合,返回一个字典。

  • 判断某一个查询集中是否有数据:

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

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


模型类关系

  1. 一对多关系ForeignKey

    例:图书类-英雄类
    models.ForeignKey() 定义在多的类中

  2. 多对多关系ManyToManyField

    例:新闻类-新闻类型类 体育新闻 国际新闻
    models.ManyToManyField() 定义在哪个类中都可以

  3. 一对一关系OneToOneField

    例:员工基本信息类-员工详细信息类. 员工工号
    models.OneToOneField 定义在哪个类中都可以



关联查询(一对多)

在一对多关系中,一对应的类我们把它叫做一类,多对应的那个类我们把它叫做多类,我们把多类中定义的建立关联的类属性叫做关联属性。
在这里插入图片描述

格式
  • 由一类的对象查询多类的时候:
    一类的对象 . 多类名小写_set.all()
    #查询所用数据

  • 由多类的对象查询一类的时候:
    多类的对象 . 关联属性
    #查询多类的对象对应的一类的对象

  • 由多类的对象查询一类对象的id时候:
    多类的对象 . 关联属性_id

    例:查询id为1的图书关联的英雄的信息。
    	b=BookInfo.objects.get(id=1)
    	b.heroinfo_set.all()
    	
    通过模型类查询:
    	HeroInfo.objects.filter(hbook__id=1)
    	例:查询id为1的英雄关联的图书信息。
    		h = HeroInfo.objects.get(id=1)
    		h.hbook
    	
    通过模型类查询:
    	BookInfo.objects.filter(heroinfo__id=1)
    
  • ==通过多类的条件查询一类的数据:
    一类名.objects.filter(多类名小写__多类属性名__条件名)

  • 通过一类的条件查询多类的数据:
    多类名.objects.filter(关联属性__一类属性名__条件名)

  • 注意

    1. 通过模型类实现关联查询时, 要查那个表中的数据, 就需要通过哪个类来查.
    2. 写关联查询条件的时候, 如果类中没有关系属性, 条件需要写对应的类名, 如果类中有关系属性, 直接写关系属性.
    例:查询图书信息,要求图书关联的英雄的描述包含'八'。
    BookInfo.objects.filter(heroinfo__hcomment__contains='八')
    
    例:查询图书信息,要求图书中的英雄的id大于3.
    BookInfo.objects.filter(heroinfo__id__gt=3)
    
    例:查询书名为“天龙八部”的所有英雄。
    HeroInfo.objects.filter(hbook__btitle='天龙八部')
    


管理器

  • 管理器是Django的模型进行数据库操作的接口,Django应用的每个模型类都拥有至少一个管理器。Django支持自定义管理器类,继承自models.Manager

    在这里插入图片描述

模型类属性

属性objects:管理器,是models.Manager类型的对象,用于与数据库进行交互。

当没有为模型类定义管理器时,Django会为每一个模型类生成一个名为objects的管理器,自定义管理器后,Django不再生成默认管理器objects。

自定义模型管理器类
  1. 自定义一个管理器类,这个类继承models.Manger类。
  2. 再在具体的模型类里定义一个自定义管理器类的对象。
自定义管理器类的应用场景
  1. 改变查询的结果集。
    比如调用BookInfo.books.all()返回的是没有删除的图书的数据。

    a)打开booktest/models.py文件,定义类BookInfoManager
    
    #图书管理器
    class BookInfoManager(models.Manager):
        def all(self):
            #默认查询未删除的图书信息
            #调用父类的成员语法为:super().方法名
            return super().all().filter(isDelete=False)
            
            
    b)在模型类BookInfo中定义管理器
    
    class BookInfo(models.Model):
        ...
        books = BookInfoManager()
    
  2. 添加额外的方法。
    管理器类中定义一个方法帮我们操作模型类对应的数据表。
    使用self.model()就可以创建一个跟自定义管理器对应的模型类对象。

    a)打开booktest/models.py文件,定义方法create。
    
    class BookInfoManager(models.Manager):
        ...
        #创建模型类,接收参数为属性赋值
        def create_book(self, title, pub_date):
            #创建模型类对象self.model可以获得模型类
            book = self.model()
            book.btitle = title
            book.bpub_date = pub_date
            book.bread=0
            book.bcommet=0
            book.isDelete = False
            # 将数据插入进数据表
            book.save()
            return book
            
    b)为模型类BookInfo定义管理器books语法如下
    class BookInfo(models.Model):
        ...
        books = BookInfoManager()
        
    c)调用语法如下:
    	调用:
    	book=BookInfo.books.create_book("abc",date(1980,1,1))
    

元选项

在模型类中定义类Meta,用于设置元信息,如使用db_table自定义表的名字。
数据表的默认名称为:

<app_name>_<model_name>
例:
booktest_bookinfo

例:指定BookInfo模型类生成的数据表名为bookinfo。

在BookInfo模型类中添加如下内容,代码如下:

#定义图书模型类BookInfo
class BookInfo(models.Model):
    ...

    #定义元选项
    class Meta:
      db_table='bookinfo' #指定BookInfo生成的数据表名为bookinfo

<补充>

重定向

页面重定向:服务器不返回页面,而是告诉浏览器再去请求其他的url地址。
在这里插入图片描述
在views中

返回应答,让浏览器再访问/index,重定向
    return HttpResponse('ok')

标签:__,Django,models,模型,BookInfo,objects,查询,id
来源: https://blog.csdn.net/weixin_44872216/article/details/100032358

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有