Django学习笔记(3):使用模型类进行查询(查询函数、F对象、Q对象、聚合函数、查询集、模型类关系、关联查询、自关联、管理器)

文章目录

  • 1.查询函数
  • 2.F对象
  • 3.Q对象
  • 4.聚合函数
  • 5.Count函数
  • 6.查询集
        • 查询集的特性
        • 对查询集进行切片
        • 判断一个查询集中是否有数据
  • 7.模型类之间的关系
        • 一对多关系
        • 多对多关系
        • 一对一关系
  • 8.关联查询(一对多)
  • 9.插入、更新和删除
  • 10.自关联
  • 11.管理器
        • 自定义管理器类
  • 12.元选项

1.查询函数

模型类.objects.函数名()

函数:
get:返回满足条件的一条数据,只能返回一条数据。参数为条件。
all:返回满足条件的查询集,QuerySet类型
filter:返回满足条件的数据。QuerySet类型,参数为条件。可以传入多个参数。
exclude:返回不满足条件的数据。QuerySet类型,参数为条件。
order_by:对查询结果进行排序。QuerySet类型

条件参数格式
判等条件id__exact==1(等价于id=1)
模糊查询
包含btitle__contains='乐',开头btitle__startswith='value',结尾btitle__endswith='value'
空查询btitle__isnull=False
查询范围id__in[1,3,5]
比较查询
id__gt=3 (great than)大于 , id__gte=3 大于等于
id__lt=3(less than)小于 ,id__lte=3 小于等于
日期查询
方法一 publish_date__year=1980
方法二 publish_date__gt=date(1980,1,1)
排序
从小到大

BookInfo.objects.all().order_by('id')

从大到小

BookInfo.objects.all().order_by('-id')

2.F对象

作用:用于类属性之间的比较

from django.db.models import F

例如:查询阅读量大于评论量

BookInfo.objects.filter(read__gt=F('comment'))

3.Q对象

作用:用于查询时条件之间的逻辑关系,not and or,可以对Q对象进行& | ~操作

from django.db.models import Q

例如:id>3且阅读量大于30

BookInfo.obkects.filter(id__gt=3,read__gt=30)
BookInfo.obkects.filter(Q(id__gt=3)&Q(read__gt=30))

例如:查询id大于3或者阅读量大于30的图书信息

BookInfo.obkects.filter(Q(id__gt=3)|Q(read__gt=30))

例如:查询id不等于3的图书信息

BookInfo.obkects.filter(~Q(id__gt=3))

4.聚合函数

对查询结果进行聚合操作:sum count avg max min
在Django中调用aggregate函数来使用聚合,返回值是一个字典。

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

例如:查询所有图书的数目

>>> BookInfo.objects.all().aggregate(Count("id"))
{'id__count': 9}

例如:所有图书的阅读量总和

>>> BookInfo.objects.all().aggregate(Sum("read"))
{'read__sum': 9245}

5.Count函数

作用:统计满足条件数据的数目,返回值是一个数字
例如:统计所有图书的数目

>>> BookInfo.objects.all().count()
9

6.查询集

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

查询集的特性

惰性查询:只有在实际使用查询集中的数据的时候才会发生数据库真正查询。
缓存:当时用的是同一个查询集时,第一次的时候会发生实际数据库的查询,然后把结果缓存,之后再使用这个查询集时,使用的是缓存中的数据。

对查询集进行切片

下标不允许为负数

>>> books=BookInfo.objects.all()
>>> books[2:5]
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]

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

使用 exists 判断,没有返回False,有返回True

>>> books=BookInfo.objects.all()
>>> books1 = books[0:0]
>>> books1.exists()
False

7.模型类之间的关系

一对多关系

models.ForeignKey()定义在多类中

多对多关系

models.ManyToManyField()定义在双方都可以

class NewsType(models.Model):
    type_name = models.CharField(max_length=20)
    
class NewsInfo(models.Model):
    title = models.CharField(max_length=120)
    pub_date = models.DateTimeField(auto_now_add=True)
    content = models.TextField()
    news_type = models.MangToManyField('NewsType')

一对一关系

models.OneToOneField() 定义在双方都可以

8.关联查询(一对多)

例:查询图书id为1的所有英雄的信息

books=BookInfo.objects.get(id=1)
books.heroInfo_set.all()

通过模型类查询:

HeroInfo.obkects.filter(hbook__id=1)

例:查询id为1的英雄关联的图书信息

h = HeroInfo.objects.get(id=1)
h.hbook

通过模型类查询:

BookInfo.objects.filter(heroinfo__id=1)//多类类名小写

9.插入、更新和删除

10.自关联

自关联是一种特殊的一对多关系
例如:地区表的父级关系,陕西省-西安市,西安市的areaParent_id为陕西省的ID

class AreaInfo(models.Model):
    areaName = models.CharField(max_length=100)
    areaParent = models.ForeignKey('self',null=True,blank=True)

11.管理器

BookInfo.objects.all()objects是一个Django自动生成的管理器对象,通过这个对象可以实现对数据的查询。objectsmodels.Manager类的一个对象。

>>> type(BookInfo.objects)
<class 'django.db.models.manager.Manager'>

自定义管理器类

自定义BookInfoManager类,这个类继承自models.Manager,并且重写all()方法。

class BookInfoManager(models.Manager):
    #user defined class of managing the bookinfo
    #override function all()
    def all(self):
        #call all() of super class
        books = super().all()
        for item in books:
            print("bookTile:"+item.bookTitle)
        return books
class BookInfo(models.Model):
    bookTitle = models.CharField(max_length=20)
    publish_date = models.DateField()
    read = models.IntegerField(default=0)
    comment = models.IntegerField(default=0)
    #Delete tag
    isDelete = models.BooleanField(default=False)
    objects = BookInfoManager()

自定义管理器方法:

class BookInfoManager(models.Manager):
    #user defined class of managing the bookinfo
    #override function all()
    def all(self):
        #call all() of super class
        books = super().all()
        for item in books:
            print("bookTile:"+item.bookTitle)
        return books
    def createBook(self,bookTitle,publish_date):
    	model_class = self.model
        obj =model_class()
        obj.bookTitle = bookTitle
        obj.publish_date = publish_date
        obj.save()
        return obj
>>> from booktest002.models import BookInfo
>>> BookInfo.objects.createBook("xcjs","1999-1-1")
<BookInfo: BookInfo object>
>>> BookInfo.objects.all()
bookTile:lldq
bookTile:xyj
bookTile:xyj
bookTile:xyj
bookTile:xyj
bookTile:xyj
bookTile:xyj
bookTile:xyj
bookTile:xyj
bookTile:jpm
bookTile:xcjs
[<BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>, <BookInfo: BookInfo object>]

可以通过self.model()获取所在模型类,这样即使模型类名发生变化,也能正常使用。

>>> BookInfo.objects.model
<class 'booktest002.models.BookInfo'>

12.元选项

模型类对应的表已经生成,此时,模型类或应用一旦改名,与数据库表名不对应就会出现问题。Django默认生成的表名:应用名小写_模型类名小写
如何解决?
使用元选项:需要在模型类中定义一个元类Meta,在里面定义一个类属性db_table就可以指定表名。

class BookInfo(models.Model):
    bookTitle = models.CharField(max_length=20)
    publish_date = models.DateField()
    read = models.IntegerField(default=0)
    comment = models.IntegerField(default=0)
    #Delete tag
    isDelete = models.BooleanField(default=False)
    objects = BookInfoManager()

    class Meta:
        db_table = "bookinfo"

指定之后,重新迁移,数据库表名就不依赖其模型类了。

你可能感兴趣的:(Django,Python,django,python,flask)