Django之ORM的操作方法总结

一、ORM常用的13个操作方法(获取对象)

介绍一个可以以py脚本方式运行ORM操作的方法:

可在项目内新建个py文件,复制项目内manage.py文件中的以下代码:

1. 必会的13条方法:

   1. models.Book.objects.all()  # 获取到所有的书籍对象,结果是对象列表

   2. models.Book.objects.get(条件)  # 获取符合条件的对象

   3. models.Book.objects.filter(条件)  # 筛选所有符合条件的,结果是对象列表

   4. models.Book.objects.exclude(条件)  # 筛选出所有不符合条件的,结果是对象列表

   5. models.Book.objects.all().values( )  # 字典列表,[ {id:1,name:20} , {id:2,name:18} ],values(‘id’)括号内不指定时显示全部,如指定则只显示指定的,[ {id:1} , {id:2,} ]

   6. models.Book.objects.all().values_list( )  # 元组列表,[ (1,20) , (2,18) ]同上,指定时显示指定内容

   7. models.Book.objects.all().order_by(id)  # 按照id升序就行排列

      models.Book.objects.all().order_by(-id)  # 按照id降序就行排列

      models.Book.objects.all().order_by(‘age’ ,-id)  # 先按age升序,age相同的按id进行降序排列

   8. models.Book.objects.all().order_by(id).reverse()  # 对结果反转; 注意reverse前必须排序,否则reverse无效; 或在model.py文件中Book类中的Meta中指定ordering=(‘id’ , )注意逗号必须有

   9. distinct():  # 去重,当获取到的结果Queryset列表中同一对象出现多次时去重,只留一个

   10. models.Book.objects.all().count()  # 计数,可统计结果个数,如对Queryset内元素数进行统计.

   11. models.Book.objects.all().first()  # 获取结果中的第一条,即使前面结果列表为空,也不会报错

   12. models.Book.objects.filter().last()  # 获取结果中的最后一条

   13.models.Book.objects.filter().exists()  # 判断Queryset列表是否有东西,结果为True或False;

2. 小结:

返回对象列表(Queryset)的方法有:

all()  
filter()  
ordey_by()  
exclude()   
values() 
values_list()   
reverse()   
distinct()

返回单个对象的方法有:

first()   last()   get()   create() #创建一个对象,且返回刚创建的对象

判断布尔值的有: exists()

返回数字的有: count()

怎么用呢?
条件格式: 模型类属性名__条件名 = 值 # 所以定义模型类属性名时不能使用多个下划线。

例如:id__exact = 1 。
1、get函数(仅能返回一条数据)。

book = BookInfo.objects.get(id__exact = 1)   # 可以且仅可以返回一条数据。 没有数据或返回多条数据都会抛异常。

book = BookInfo.objects.get(id = 1)   # 简写形式。  __exact可以省略。返回模型对象

2、all函数 (查询所有)

books = BookInfo.objects.all()   # 查询所有。 返回QuerySet查询集(可以遍历)

3、filter函数 (条件查询)

#条件查询。(可以通过逗号,连接多个条件)  返回QuerySet查询集(可以遍历)

books = BookInfo.objects.filter(title__exact = '天龙八部')  # __exact 等于。 __exact 可以省略。 (__iexact 不区分大小写)

books = BookInfo.objects.filter(title__contains = '天')  # __contains 包含。模糊查询。 (__icontains 不区分大小写)

books = BookInfo.objects.filter(title__endswith = '部')  # __endswith 以..结尾。 __startswith 以..开头。 (__iendswith 不区分大小写)

books = BookInfo.objects.filter(title__isnull = False)  # __isnull 是否为空。 True:表示为null。 False表示not null。

books = BookInfo.objects.filter(id__in = [1,3,5])  # __in 范围查询。

books = BookInfo.objects.filter(id__gt = 3)  # __gt 大于。 __lt 小于。 __gte 大于等于。 __lte 小于等于。

books = BookInfo.objects.filter(pub_date__gt = date(1980,1,1))  # 日期查询。

books = BookInfo.objects.filter(pub_date__year = 1980)   # 日期查询。(year、month、day、week_day、hour、minute、second)

4、exclude函数 (filter函数取反)

# 查询id不为3的所有图书。

books = BookInfo.objects.exclude(id = 3)  # 与filter函数作用相反。 返回QuerySet查询集(可以遍历)

5、order_by函数 (排序)

#对查询结果进行排序。 返回QuerySet查询集(可以遍历)

books = BookInfo.objects.all().order_by('-id')   # 'id'表示升序; '-id'表示降序。

books = BookInfo.objects.order_by('-id')    #  .all()可以省略。 默认查询所有。 可以结合filter等函数一起使用 。

二、ORM model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

1.多表连接查询:感觉django太牛批了。

  class A(models.Model):
    name = models.CharField(u'名称')
  class B(models.Model):
    aa = models.ForeignKey(A)
B.objects.filter(aa__name__contains='searchtitle')

2 .反向查询,感觉django太太太NX了。

  class A(models.Model):
    name = models.CharField(u'名称')
  class B(models.Model):
    aa = models.ForeignKey(A,related_name="FAN")
    bb = models.CharField(u'名称')
  #查A: 
  A.objects.filter(FAN__bb='XXXX')

都知道related_name的作用,A.FAN.all()是一组以A为外键的B实例,
可前面这样的用法是查询出所有(B.aa=A且B.bb=XXXX)的A实例,
然后还可以通过__各种关系查找,很好用!!!

3.条件选取querySet的时候,filter表示=,exclude表示 !=。

querySet.distinct() 去重复
__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”)

即q1.filter(pub_date__gte=datetime.date.today())表示为时间>=now,q1.exclude(pub_date__gte=datetime.date.today())表示为<=now

“在django models中取得一个字段的distinct值”。就是select distinct xxx from table_name …这样的功能。使用values会生成ValuesQuerySet(形如N个dict组成的list),猜测大数据无额外性能影响,毕竟queryset系列都是使用时才查询操作的。
xxxx.objects.values(“field_name”).distinct()
#或者
xxxx.objects.distinct().values(“field_name”)
这两句生成的sql语句相同,原帖地址:http://blog.csdn.net/tsbob/article/details/1340293。

关于缓存:
queryset是有缓存的,a = A.objects.all(),print [i for i in a].第一次执行打印会查询数据库,然后结果会被保存在queryset内置的cache中,再执行print的时候就会取自缓存。
很多时候会遇到仅需判断queryset是否为空的情况,可以1. if queryset:pass 2.if queryset.count>0:pass 3.if queryset.exists():pass. 三种方式性能依次提升。
当queryset非常巨大时,cache会成为问题。此时可以queryset.iterator(),迭代器的用处就不多说了,根据具体需求情况使用。

三、django orm 常用的查询筛选条件

大于:__gt、大于等于: __gte
小于:__lt、小于等于:__lte
in
like
is null / is not null
不等于/不包含于
其他模糊查询

model

class User(AbstractBaseUser, PermissionsMixin):
    uuid = ShortUUIDField(unique=True)
    username = models.CharField(max_length=100, db_index=True, unique=True, default='')
    schoolid = models.CharField(max_length=100, null=True, blank=True, default='')
    classid = models.CharField(max_length=100, null=True, blank=True, default='')
    fullname = models.CharField(max_length=50, default='', null=True, blank=True)
    email = models.EmailField(_('email address'), blank=True, null=True)
    age = models.SmallIntegerField(default=0)

大于,大于等于

__gt  大于
__gte  大于等于

User.objects.filter(age__gt=10)    # 查询年龄大于10岁的用户
User.objects.filter(age__gte=10)  # 查询年龄大于等于10岁的用户

小于、小于等于

__lt  小于
__lte 小于等于

User.objects.filter(age__lt=10)     # 查询年龄小于10岁的用户
User.objects.filter(age__lte=10)   # 查询年龄小于等于10岁的用户

in

__in

#查询年龄在某一范围的用户
User.objects.filter(age__in=[10, 20, 30])

link

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

is null / is not null

#__isnull  判空

User.objects.filter(username__isnull=True)    # 查询用户名为空的用户
User.objects.filter(username__isnull=False)  # 查询用户名不为空的用户

其他模糊查询

__startswith #以…开头
__istartswith #以…开头 忽略大小写
__endswith #以…结尾
__iendswith #以…结尾,忽略大小写
__range #在…范围内
__year #日期字段的年份
__month #日期字段的月份
__day #日期字段的日

四、Django ORM 查询,删除,更新操作

ORM 查询操作
修改 views.py 文件

from django.shortcuts import render, HttpResponse
from app01 import models
from  app01.models import Book,Author,Publisher

def data_oper(req):
    # 获取 book 表 id 为2的价格
    book = models.Book.objects.filter(id=2).values("price")
    print(book)

    # 获取 author 表 id 为 1 的名字
    authors = models.Author.objects.filter(id=1)[0]
    print(authors)

    # 获取 author 表 id 为 3 名字
    author1 = models.Author.objects.get(id=3)
    print(author1)

    # 以 id 为倒序排列输出记录
    author2 = models.Author.objects.order_by("-id")
    print(author2)

    return HttpResponse("Hello world")

获取除了 id 为2 的 book
book = models.Book.objects.exclude(id=2)

反向查找

from django.shortcuts import render, HttpResponse
from app01 import models
from  app01.models import Book,Author,Publisher

def data_oper(req):
    # 查找 Publish name 是 广东工业出版社 的 书籍
    obj=models.Publisher.objects.filter(name="广东工业出版社")[0]
    print(obj.book_set.all().values("title"))

    return HttpResponse("Hello world")
def data_oper(req):
    # 查找书籍名为 K8S 的出版社名字
    print(models.Publisher.objects.filter(book__title="K8S").values("name"))
    # 查找出版社名为 广东工业出版社 的书籍名字
    print(models.Book.objects.filter(publisher__name="广东工业出版社").values("title"))

    return HttpResponse("Hello world")
from django.shortcuts import render, HttpResponse
from app01 import models
from  app01.models import Book,Author,Publisher

def data_oper(req):
    # 查询所有出版社城市为 广州 的书名
   ret = models.Book.objects.filter(publisher__city='广州').values('title')
    print(ret)

    # 查询对应操作的sql语句
    print(ret.query)

    return HttpResponse("Hello world")

ORM 删除操作

from django.shortcuts import render, HttpResponse
from app01 import models
from  app01.models import Book,Author,Publisher

def data_oper(req):
    # 多对多的情况下,删除 book id 为1,author id 大于0的记录
    book = models.Book.objects.filter(id=2)[0]
    authors = models.Author.objects.filter(id__gt=0)
    book.authors.remove(*authors)

    # 删除单条记录,删除 book 表中 id 为 1 的记录
    models.Book.objects.filter(id=1).delete()



    return HttpResponse("Hello world")

ORM 更新操作
修改 views.py 文件

from django.shortcuts import render, HttpResponse
from app01 import models
from  app01.models import Book,Author,Publisher

def data_oper(req):
    # 把 author id 为 3 的 name 改为 katy
    author = models.Author.objects.get(id=3)
    author.name = "katy"
    author.save()

    return HttpResponse("Hello world")
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值