一、django的orm的13种基本的查询方法

1、all方法,查询某张表中的所有的数据

user_obj_list = models.Person.objects.all()

  

返回的结果是queryset对象,也就是一个对象的集合

<QuerySet [<Person: 人的对象小黑9>, <Person: 人的对象小黑8>, <Person: 人的对象小黑7>, <Person: 人的对象小黑6>, <Person: 人的对象小黑5>, <Person: 人的对象小黑4>, <Person: 人的对象小黑3>, <Person: 人的对象小黑2>, <
Person: 人的对象小黑19>, <Person: 人的对象小黑18>, <Person: 人的对象小黑17>, <Person: 人的对象小黑16>, <Person: 人的对象小黑15>, <Person: 人的对象小黑14>, <Person: 人的对象小黑13>, <Person: 人的对象小黑12>, <Pers
on: 人的对象小黑11>, <Person: 人的对象小黑10>, <Person: 人的对象小黑1>, <Person: 人的对象小黑0>]>

  

2、filter方法,查询符合某个条件的所有的数据

user_objs = models.Person.objects.filter(name="小黑7")

返回的结果也是一个queryset对象,也就是一个对象的集合

<QuerySet [<Person: 人的对象小黑7>]>

  

3、get方法,返回的单个对象

user_obj = models.Person.objects.get(name="小黑7")

  

返回的是单个对象

人的对象小黑7

  

# 返回的时候某一个具体的对象,如果这个条件的对象不存在,会报错

4、exclude方法,对条件取反

user_obj = models.Person.objects.exclude(id__gte=4)

  

返回的是一个queryset对象的

exclude方法 <QuerySet [<Person: 人的对象小黑2>, <Person: 人的对象小黑1>, <Person: 人的对象小黑0>]>

  

5、values方法,查询一个queryset对象的值

user_obj = models.Person.objects.exclude(id__gte=4).values("id","name","birthday_1")

  

返回的是一个一个queryset的对象集合,是一个大的列表,每个列表的元素又是每个对象的小字典

<QuerySet [{'id': 3, 'name': '小黑2', 'birthday_1': datetime.datetime(2016, 12, 6, 0, 0)}, {'id': 2, 'name': '小黑1', 'birthday_1': datetime.datetime(2016, 5, 13, 0, 0)}, {'id': 1, 'name': '小黑0', 'birthday_1':
datetime.datetime(2016, 3, 5, 0, 0)}]>

  

6、values_list,查询一个queryset对象的值

user_obj = models.Person.objects.exclude(id__gte=4).values_list("id", "name", "birthday_1")

  

返回的是一个queryset对象,这个对象是一个列表,列表中的每个元素是每个对象的元组信息

<QuerySet [(3, '小黑2', datetime.datetime(2016, 12, 6, 0, 0)), (2, '小黑1', datetime.datetime(2016, 5, 13, 0, 0)), (1, '小黑0', datetime.datetime(2016, 3, 5, 0, 0))]>

  

7、order_by,根据某个字段排序,如果字段加一个负号,则是逆序排序,如果不加,则则是正序排列

user_obj = models.Person.objects.exclude(id__gte=4).order_by("-id")

  

返回的结果也是一个queryset对象

<QuerySet [<Person: 人的对象小黑2>, <Person: 人的对象小黑1>, <Person: 人的对象小黑0>]>

  

user_obj = models.Person.objects.exclude(id__gte=4).order_by("id")

  

返回的结果也是一个queryset对象

<QuerySet [<Person: 人的对象小黑0>, <Person: 人的对象小黑1>, <Person: 人的对象小黑2>]>

  

8、reverse方法,对一个有序的queryset对象,做反转操作

user_obj = models.Person.objects.exclude(id__gte=4).order_by("-id").reverse()

  

返回的结果

<QuerySet [<Person: 人的对象小黑0>, <Person: 人的对象小黑1>, <Person: 人的对象小黑2>]>

  

9、distance方法,对返回的数据去重,在外键中用的比较多

10、count方法,统计查询到的数据的个数

11、first方法,在queryset对象中返回查询到的第一条数据

12、last方法,在queryset对象中返回查询到的最后一条数据

13、exists方法,判断用指定的过滤条件查询是否有值

二、单表查询中的双下划线查询

_exact 精确等于 like 'aaa'

 __iexact 精确等于 忽略大小写 ilike 'aaa'

 __contains 包含 like '%aaa%'

 __icontains 包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains。

__gt 大于

__gte 大于等于

__lt 小于

__lte 小于等于

__in 存在于一个list范围内

__startswith 以...开头

__istartswith 以...开头 忽略大小写

__endswith 以...结尾

__iendswith 以...结尾,忽略大小写

__range 在...范围内

__year 日期字段的年份

__month 日期字段的月份

__day 日期字段的日

__isnull=True/False

例子:

>> q1 = Entry.objects.filter(headline__startswith="What")

>> q2 = q1.exclude(pub_date__gte=datetime.date.today())

>> q3 = q1.filter(pub_date__gte=datetime.date.today())

>>> q = q.filter(pub_date__lte=datetime.date.today())

>>> q = q.exclude(body_text__icontains="food")

  

    models.test_orm.objects.filter(id__in=[12,34,21])
models.test_orm.objects.filter(id__gt=12)
models.test_orm.objects.filter(name__icontains="aaaa")
models.test_orm.objects.filter(name__iendswith="aaa")

  

三、一对多的查询

1、先看正向查询,有两种方式,方式1,先在多表中找到某个对象,然后通过外键的字段找到一表中的对象

    book_obj = models.Book.objects.all().last()

    print(book_obj.book_publish)

    print(book_obj.book_publish.name)

  

2、正向查询的方式2,在values和values_list中利用外键字段的双下划线进行跨表查询

    # 通过双下划线在values中进行跨表查询,需要通过外键的字段
publist_obj = models.Book.objects.filter(id=3).values("id","book_name","book_publish","book_publish__name") print(publist_obj) # 通过双下划线在values_list中进行跨表查询,需要通过外键的字段
publist_obj = models.Book.objects.filter(id=3).values_list("id","book_name","book_publish","book_publish__name") print(publist_obj)

  

3、在看反向查询

我们先来介绍一下外键中的related_name字段,如果,如果设置了这个值,则反向查询的时候用related_name的值,如果没有设置这个值,则通过“多表的名称_set”进行反向查询

首先我们看下不设置related_name的反向查询

首先外键是这样设置的

    book_publish = models.ForeignKey(to="Publisher")

  

然后进行反向查询,这里要记住,如果使用values或者values_list方法,则里面的参数和正向查询是一样的

    publist_obj = models.Publisher.objects.all().first()

    print(publist_obj.book_set.all())
print(publist_obj.book_set.values_list("id","book_name","book_publish","book_publish__name"))

  

然后我们在看下在外键中设置related_name的方向查询,下面的例子,我们设置了ralated_name,所以反向查询则要使用PubToBook进行反向查询

book_publish = models.ForeignKey(to="Publisher", related_name="PubToBook")

  

同样,在values和values_list方法中,则里面的参数和正向查询是一样的

    print(publist_obj.PubToBook.all())
print(publist_obj.PubToBook.values_list("id", "book_name", "book_publish", "book_publish__name"))

  

这里要注意,如果要调用values和values_list方法,则必须要用queryset对象

如果要使用点,则必须要单个对象

四、多对多操作

1、create操作

    # 1、方法1,create

    # 我们的manytomant字段在book表中,我们可以调用book表中的某个对象的create方法,去创建一个auther对象,创建成功后,会自动把这个book对象和
# 和我们新创建的出版社关联起来 # book_obj = models.Book.objects.get(id=2) # book_obj.book_auther.create(
# auther_name = "大学作者10",
# )

  

2、add操作

    # 2、add方法
# 1、由于manytomany字段在book表中,我们可以先查到某个或者某几个auther表中的对象,某个book对象通过manytomany字段
# 为某本书添加和多个auther表的关联,这里还可以传递一个列表对象,则需要用*列表对象传递进去,可以添加一个对象,也可以
# 添加多个对象,也可以传递一个列表进去
#
# auther_1 = models.Auther.objects.all().first()
# auther_2 = models.Auther.objects.get(id=2)
#
# models.Book.objects.all().last().book_auther.add(
# auther_1,auther_2
# ) # add的方法也可以直接传递一个id的值进去

  

3、remove操作

    # 3、remove方法
# 先在book表中找到某个对象,然后通过多对多字段进行remove操作,删除这个book和作者的关系 # book_obj = models.Book.objects.all().first() # 3_1、可以直接传递一个id进去
# book_obj.book_auther.remove(11) # 3_2、传递一个对象进去 # del_auther_obj = models.Auther.objects.get(id=5)
#
# book_obj.book_auther.remove(del_auther_obj)

  

4、clear方法

    # 4、clear方法

    book_obj = models.Book.objects.all().first()

    book_obj.book_auther.clear()

  

五、聚合查询

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

  

    ret = models.Book.objects.all().aggregate(Sum("book_price"))
print(ret) ret = models.Book.objects.all().aggregate(Avg("book_price"))
print(ret) ret = models.Book.objects.all().aggregate(Max("book_price"))
print(ret) ret = models.Book.objects.all().aggregate(Min("book_price"))
print(ret)

  

结果如下

{'book_price__sum': Decimal('468.98')}
{'book_price__avg': 46.898}
{'book_price__max': Decimal('99.43')}
{'book_price__min': Decimal('14.43')}

  

六、分组查询

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

  

先通过values方法进行分组,然后求每个分组下的最大值,平均值,最小值,和,通过表中的所有字段都可以做分组查询

    ret = models.Book.objects.all().values("book_publish").annotate(Sum("book_price"))
print(ret) ret = models.Book.objects.all().values("book_auther").annotate(Min("book_price"))
print(ret) ret = models.Book.objects.all().values("book_name").annotate(Max("book_price"))
print(ret)

  

结果

<QuerySet [{'book_publish': 10, 'book_price__sum': Decimal('102.93')}, {'book_publish': 15, 'book_price__sum': Decimal('88.86')}, {'book_publish': 16, 'book_price__sum': Decimal('48.84')}, {'book_publish': 17, 'bo
ok_price__sum': Decimal('34.49')}, {'book_publish': 18, 'book_price__sum': Decimal('99.43')}, {'book_publish': 19, 'book_price__sum': Decimal('94.43')}]>
<QuerySet [{'book_auther': None, 'book_price__min': Decimal('34.23')}, {'book_auther': 1, 'book_price__min': Decimal('14.43')}, {'book_auther': 2, 'book_price__min': Decimal('34.41')}, {'book_auther': 3, 'book_pri
ce__min': Decimal('14.43')}, {'book_auther': 4, 'book_price__min': Decimal('32.43')}, {'book_auther': 7, 'book_price__min': Decimal('34.49')}, {'book_auther': 8, 'book_price__min': Decimal('56.43')}, {'book_auther
': 9, 'book_price__min': Decimal('94.43')}, {'book_auther': 10, 'book_price__min': Decimal('94.43')}]>
<QuerySet [{'book_name': '大学体育1', 'book_price__max': Decimal('34.23')}, {'book_name': '大学体育2', 'book_price__max': Decimal('56.43')}, {'book_name': '跟周雍博学玩游戏', 'book_price__max': Decimal('14.43')},
{'book_name': '跟妈妈学做饭', 'book_price__max': Decimal('34.47')}, {'book_name': '跟小妹学哭鼻子', 'book_price__max': Decimal('34.49')}, {'book_name': '跟崔洪艳学会计', 'book_price__max': Decimal('34.41')}, {'boo
k_name': '跟崔皓然学爬楼梯', 'book_price__max': Decimal('32.43')},, {'book_name': '跟爷爷学木匠', 'book_price__max': Decimal('94.43')}, {'book
_name': '跟爸爸学开车', 'book_price__max': Decimal('34.23')}]>

  

分组查询的高级用法,求每个作者出的book的总价格

   ret = models.Auther.objects.all().annotate(book_price_sum=Sum("book__book_price")).values_list("auther_name","book_price_sum")
print(ret)

  

结果如下

<QuerySet [('大学作者0', Decimal('266.42')), ('大学作者1', Decimal('133.84')), ('大学作者2', Decimal('83.31')), ('大学作者3', Decimal('200.50')), ('大学作者4', None), ('大学作者5', None), ('大学作者6', Decimal('12
8.92')), ('大学作者7', Decimal('56.43')), ('大学作者8', Decimal('94.43')), ('大学作者9', Decimal('94.43')), ('大学作者10', None)]>

  

下面来解释一下上面的代码

先拿到所有的作者,然后求出每个作者的书的总价格,然后赋值给一个变量book_price_sum,赋值给的这个变量后,也就是在数据库中会临时多一个字段,这个字段就是book_price_sum,然后通过values_list方法打印出作者名称和book_price_sum的值,由于作者表中没有manytomany字段,需要用表明+下划线的方法做跨表查询

下面这段代码更好理解,实现的效果和上面的一样

    ret = models.Auther.objects.all().values("auther_name").annotate(book_price_sum=Sum("book__book_price")).values_list("auther_name",
"book_price_sum")
print(ret)

  

7、F查询

   from django.db.models import F
from django.db.models import Q # 当我们需要对表中的 数字字段做比较或者操作的时候加减乘除等数学运算的时候可以用到F查询 print("F查询".center(100,"*")) # 过滤出来kucun字段大于卖出字段的值
ret = models.Book.objects.filter(kucun__gt=F("maichu"))
print(ret) # 为库存字段+2
models.Book.objects.all().update(kucun=F("kucun")+2)

  

8、Q查询

append的方法需要传递一个tuple

   q_obj = Q()

    q1 = Q()
q2 = Q() q1.connector = "AND" q1.children.append(("id__gte",3))
  
q1.children.append(("kucun__gte",1000)) q2.connector = "OR" q2.children.append(("maichu__lte",3000)) q_obj.add(q1,"AND")
q_obj.add(q2,"AND") # 过滤条件1:id大于等于3,库存大于等于1000的,两个条件是AND的关系
# 过滤条件2:卖出小于等于3000的,如果在q2中继续添加条件,他是or的关系
# 最后过滤条件1和过滤条件2是AND的关系 ret = models.Book.objects.filter(q_obj).values("id","kucun","maichu")
print(ret)

  

结果如下

<QuerySet [{'id': 4, 'kucun': 1012, 'maichu': 299}, {'id': 9, 'kucun': 4010, 'maichu': 19}]>

  

9、一对一操作

我们可以把一张表中不常用的字段,或者不重要的字段放在另外一张表中,比如我们通过qq去登录第三方的网站,这个时候就可以把一些不重要的字段暴露给第三方网站,而不用把很重要的信息暴漏给第三方网站

先看下我们设计的表

class partent(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
details = models.OneToOneField(to="details_info",related_name="reverse_look_partent") class Meta:
unique_together = ("name","pwd") def __str__(self):
return self.name class details_info(models.Model):
sex = models.CharField(max_length=32)
addr = models.CharField(max_length=64,null=True)
phone = models.PositiveIntegerField(unique=True) def __str__(self):
return self.phone

  

如果我们要给表中增加数据,则需要先给details_info表中插入数据,然后在为parent表中插入数据

为details_info表中插入数据

    import random
for i in range(5):
models.details_info.objects.create(
sex = "man",
addr = "深圳" + str(random.randint(1,10000)),
phone = random.randint(100000000,900000000)
)

  

在为parent表中插入数据

    for i in models.details_info.objects.all().values_list("id"):

        models.partent.objects.create(
name = "小黑" + str(i[0]),
pwd = "password" + str(random.randint(100000000,900000000)),
details_id = int(i[0]), )

  

最后我们看下一对一的正向和反向查询

分别验证通过对象和query_set对象进行查询

    p_obj = models.partent.objects.all().last()

    print("一对一的正向查询1",p_obj.details.phone)

    i = models.partent.objects.all().first().id

    p_obj = models.partent.objects.filter(id=i)

    print("一对一的正向查询2",p_obj.values("id","name","details__phone"))

  

在看下反向查询

    d_obj = models.details_info.objects.all().first()

    print("一对一的反向查询1",d_obj.reverse_look_partent.name)

    i = models.details_info.objects.all().last().id

    d_obj = models.details_info.objects.filter(id=i)

    print("一对一的反向查询2",d_obj.values("reverse_look_partent__id","reverse_look_partent__name","reverse_look_partent__pwd","sex","addr","phone"))

  

我们重点看下通过query_set对象进行反向查询这里

10、多对多的其他方式,手动创建第三张表的方式,之前学的时候由django为我们创建的第三张表,下面我们我们介绍下由我们自己创建第三张表时间多对多的方式

先看下数据库的表结构,用两个外键来实现多对多

class Student(models.Model):
name = models.CharField(max_length=64)
age = models.PositiveSmallIntegerField() class Meta:
unique_together = ("name","age") def __str__(self):
return self.name class Role(models.Model):
role_name = models.CharField(max_length=63,unique=True) def __str__(self):
return self.role_name class Student2Role(models.Model):
to_student = models.ForeignKey(to="Student")
to_role = models.ForeignKey(to="Role")

  

如果要进行跨表查询,只能去第三张表通过表名去查询

def manytomany(request):
ret = models.Student2Role.objects.filter(to_student_id=1).values_list("to_role") print(ret) ret = [i[0] for i in ret] ret = models.Role.objects.filter(id__in=ret).values_list("role_name")
print(ret) return HttpResponse("manytomany")

  

Django的model操作中一些常用的小点的更多相关文章

  1. django的Model 模型中常用的字段类型

    常用的字段类型: AutoField:自增长字段,通常不用,如果未在Model中显示指定主键,django会默认建立一个整型的自增长主键字段 BooleanField:布尔型,值为True或False ...

  2. 提高django model效率的几个小方法

    django的model效率不是很高,特别是在做大量的数据库操作的时候,如果你只用django来开企业站或者外包项目的话,那可以小跳过下,而你恰巧是效率狂或者说是对程序的效率要求比较高的话,那就要注意 ...

  3. Django之Model操作

    Django之Model操作 本节内容 字段 字段参数 元信息 多表关系及参数 ORM操作 1. 字段 字段列表 AutoField(Field) - int自增列,必须填入参数 primary_ke ...

  4. Python之路【第二十二篇】:Django之Model操作

    Django之Model操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...

  5. Django之Model组件

    Model组件在django基础篇就已经提到过了,本章介绍更多高级部分. 一.回顾 1.定义表(类) ##单表 from django.db import models class user(mode ...

  6. Django 07 Django模型基础2 (常用查询和多表关联)

    Django 07 Django模型基础2 (常用查询和多表关联) 一.常用查询 #查找数据 def search_user(request): #获取 rs = User.objects.first ...

  7. django (四) model模型

    models模型 1. models 定义属性 概述 django根据属性的类型确定以下信息 ·当前选择的数据库支持字段的类型 ·渲染管理表单时使用的默认html控件 ·在管理站点最低限度的验证 dj ...

  8. ES6中常用的小技巧,用了事半功倍哦

    ES6中常用的小技巧,如果能在实际项目中能使用到,必定事半功倍: 1. 强制要求参数 ES6提供了默认参数值机制,允许你为参数设置默认值,防止在函数被调用时没有传入这些参数. 在下面的例子中,我们写了 ...

  9. Django的Model上都有些什么

    Django的Model上都有些什么 modelinfo= ['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__' ...

随机推荐

  1. linux 内核假死循环导致的问题

    [, comm: -IFileSender Tainted: G B ENX -- ZTE Grantley/S1008 [:[<ffffffff810fb2cb>] [<fffff ...

  2. 【359】scikit learn 官方帮助文档

    官方网站链接 sklearn.neighbors.KNeighborsClassifier sklearn.tree.DecisionTreeClassifier sklearn.naive_baye ...

  3. openvas开放式漏洞评估系统

    OpenVAS是开放式漏洞评估系统,也可以说它是一个包含着相关工具的网络扫描器.其核心部件是一个服务器,包括一套网络漏洞测试程序,可以检测远程系统和应用程序中的安全问题. 用户需要一种自动测试的方法, ...

  4. [C语言]使用函数

    ------------------------------------------------------------------------------------------ //函数原型声明: ...

  5. 使用DOM的方法获取所有li元素,然后使用jQuery()构造函数把它封装为jQuery对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. angularjs 与 UEditor开发,添加directive,保证加载顺序正常

    'use strict'; angular.module('app.core').directive('ueditor', [function () { return { restrict: 'A', ...

  7. 学JS的心路历程-JS支持面向对象?(一)

    昨天在看Prototype看到JS支持面向对象,被前辈问到说那什么是面向对象?JS是面向对象语言吗? 便开始了一连串艰辛爬文过程,今天就来看一下两者有什么差异吧(rgwyjc)! 首先面向对象有三大特 ...

  8. SQL思维导图总结

  9. ubuntu16 安装openssh-server 一直安装不上Unable to correct problems, you have held broken packages

    zengqi@zengqi:~$ sudo apt-get install openssh-server Reading package lists... DoneBuilding dependenc ...

  10. export default 与 export

    export default 只能导出一个 可以用任意的变量来接收 export 可以暴露多个成员,需要用 import {} 接受成员 需要用名字接受 名字必须跟导出名字一致  //或者as作为别名 ...