django QuerySet API

Django模型中偶尔我们学到了一些基本的创建也查询。这里专门来讲一下数据库接口相关的接口(QuerySet API)

从数据库中查询出来的结果一般是一个集合,这个集合叫做QuerySet文中的例子大部分是基于这个blog/models.py

from django.db import models
# Create your models here.

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.IntegerField()

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.TextField()
    
    def __str__(self):
        return self.name


class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()
    
    def __str__(self):
        return self.headline
1、QuerySet 创建对象的方法
In [2]: from people.models import *

In [3]: b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')

In [4]: b.save()

总之,一共有四种方法

方法一:

In [5]: Author.objects.create(name='liu', email='123@163.com')
Out[5]: <Author: liu>

方法二:

In [6]: a = Author(name='gao', email='234@163.com')

In [7]: a.save()

方法三:

In [8]: a1 = Author()

In [9]: a1.name='yang'

In [10]: a1.email='345@163.com'

In [11]: a1.save()

方法四:

In [12]: Author.objects.get_or_create(name='ya',email='456@163.com')
Out[12]: (<Author: ya>, True)

In [13]: Author.objects.get_or_create(name='ya',email='456@163.com')
Out[13]: (<Author: ya>, False)
# 首先尝试获取,不存在就创建,可以防止重复
# 返回值(object,True/False)

备注:前三种方法返回的都是对应的object,最后一种方法返回的是一个元组,(object,True/False),创建时返回True,已存在时返回False
当有一对多、多对一、或者多对多的关系的时候,先把相关的对象查询出来

In [27]:entry = Entry.objects.get(id=1)

In [28]: cheese_blog = Blog.objects.get(name='Beatles Blog')

In [29]: entry.blog = cheese_blog

In [30]: entry.save()
2、获取对象的方法
In [34]: Author.objects.all()  # 查询所有
Out[34]: <QuerySet [<Author: liu>, <Author: gao>, <Author: yang>, <Author: ya>]>

In [35]: Author.objects.all()[:4]
Out[35]: <QuerySet [<Author: liu>, <Author: gao>, <Author: yang>, <Author: ya>]>  # 切片操作,获取4个人,不支持负索引,切片可以节约内存,不支持负索引,后面有相应解决办法,第7条

In [36]: Author.objects.get(name='liu')
Out[36]: <Author: liu>  # 名称为 WeizhongTu 的一条,多条会报错
 
#get是用来获取一个对象的,如果需要获取满足条件的一些人,就要用到filter
In [37]: Author.objects.filter(name='liu')
Out[37]: <QuerySet [<Author: liu>]>  # 等于

In [38]: Author.objects.filter(name__exact='liu')
Out[38]: <QuerySet [<Author: liu>]>  # 名称为 abc 但是不区分大小写,可以找到 ABC, Abc, aBC,这些都符合条件
 
In [39]: Author.objects.filter(name__regex='^liu')
Out[39]: <QuerySet [<Author: liu>]>  # 正则表达式查询
 
# filter是找出满足条件的,当然也有排除符合某条件的
In [40]: Author.objects.exclude(name__contains='y')
Out[40]: <QuerySet [<Author: liu>, <Author: gao>]>  # 排除包含 "y" 的Author对象

In [44]: Author.objects.exclude(email='345@163.com').filter(name__contains='y')
Out[44]: <QuerySet [<Author: ya>]>  # 找出名称含有"y", 但是排除email是'345@163.com'的
3、删除符合条件的结果

和上面类似,得到满足条件的结果,然后delete就可以(危险操作,正式场合操作务必慎重),比如:

In [47]: Author.objects.filter(name__contains='g').delete()
Out[47]: (2, {'people.Author': 2, 'people.Entry_authors': 0})  # 删除 名称中包含“g”得人

In [48]: Author.objects.filter(name__contains='g').delete()
Out[48]: (0, {})  # 没有名称中包含”g“的人

In [49]: a = Author.objects.filter(name__contains='g')
In [50]: a.delete()
Out[50]: (0, {})  # 写成两条语句也是可以的,效果一样,但是实际上Django只执行了一条SQL语句
4、更新某个内容

批量更新,适用于all()、filter()、exclude()等后面(危险操作,正式场合操作务必慎用)

In [64]: Author.objects.filter(name__contains='l').update(name="sansa")
Out[64]: 2  # 名字中包含“l”得人都改成“sansa” 返回2,说明修改了两条数据

In [65]: Author.objects.filter(name__contains='s')
Out[65]: <QuerySet [<Author: sansa>, <Author: sansa>]>

单个object更新,适合于.get(),get_or_create(),update_or_create()等得到的obj,和新建很类似。

In [4]: a = Author.objects.get(name="li")

In [5]: a.name="lil"

In [6]: a.email="111@111.com"

In [7]: a.save()  # 最后不要忘记保存!!!
5、QuerySet 是可迭代的
In [20]: a = Author.objects.all()

In [21]: for e in a:
    ...:     print(e)
    ...:     
lil
ya
gao
yang

Author.objects.all() 或者 QuerySet 是查询所有的Author条目。
注意事项:
1、如果只检查Author中是否有对象,应该用

In [22]: Author.objects.all().exists()
Out[22]: True

2、QuerySet 支持切片,可以节省内存

In [23]: Author.objects.all()[:2]
Out[23]: <QuerySet [<Author: lil>, <Author: ya>]>

3、用len(a)可以得到Author的数量,但是推荐用:

In [24]: Author.objects.count()
Out[24]: 4
# 或者用的是SQL:select count(*)

4、list(a)可以强行将QuerySet变成列表

6、QuerySet是可以用pickle序列化到硬盘在读取出来的
>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.
7、QuerySet 查询结果排序

作者按照名称排序

In [27]: Author.objects.all().order_by('name')
Out[27]: <QuerySet [<Author: gao>, <Author: lil>, <Author: ya>, <Author: yang>]>

In [28]: Author.objects.all().order_by('-name')
Out[28]: <QuerySet [<Author: yang>, <Author: ya>, <Author: lil>, <Author: gao>]>
# 在column name 前面加一个负号,可以实现倒序
8、QuerySet 支持链式查询
In [39]: Author.objects.filter(name__contains='y').filter(email="456@163.com")
Out[39]: <QuerySet [<Author: ya>]>
9、QuerySet 不支持负索引
In [56]: Author.objects.all()
Out[56]: <QuerySet [<Author: lil>, <Author: ya>, <Author: gao>, <Author: yang>]>

In [57]: Author.objects.all().reverse()
Out[57]: <QuerySet [<Author: lil>, <Author: ya>, <Author: gao>, <Author: yang>]>  # 直接用reverse()并没有起作用

In [58]: Author.objects.all().order_by('name')
Out[58]: <QuerySet [<Author: gao>, <Author: lil>, <Author: ya>, <Author: yang>]>  # 按照名字排序

In [59]: Author.objects.all().order_by('name').reverse()
Out[59]: <QuerySet [<Author: yang>, <Author: ya>, <Author: lil>, <Author: gao>]>  # 按照名字排序之后再逆序reverse()正常使用
10、QuerySet 重复问题,使用distinct() 去重

一般情况下,QuerySet 中不会出来重复问题,重复是很罕见的,但是当跨域多张表进行检索后,结果并到一起,可能会出来重复的值(遇到的问题)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 3,985评论 0 8
  • django 学习笔记,转载自自强学堂 数据库接口相关的接口(QuerySet API) 在models.py中 ...
    vonhng阅读 374评论 0 1
  • Django 1.8.2 文档Home | Table of contents | Index | Modules...
    轩辕小爱阅读 2,441评论 0 2
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 35,143评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,093评论 19 139

友情链接更多精彩内容