django模型使用操作

数据库操作—增、删、改、查

一、 增加

增加数据有两种方法。

1)save

通过创建模型类对象,执行对象的save()方法保存到数据库中。

>>> from datetime import date
>>> book = BookInfo(
    btitle='西游记',
    bput_date=date(1988,1,1),
    bread=10,
    bcomment=10
)
>>> book.save()
>>> hero = HeroInfo(
    hname='孙悟空',
    hgender=0,
    hbook=book
)
>>> hero.save()
>>> hero2 = HeroInfo(
    hname='猪八戒',
    hgender=0,
    hbook_id=book.id
)
>>> hero2.save()

2)create

通过模型类.objects.create()保存。

>>> HeroInfo.objects.create(
hname='沙悟净',
hgender=0,
hbook=book
)
<HeroInfo: 沙悟净>
创建对象 create(), bulk_create(), update_or_create() 创建,批量创建,创建或更新

二、修改

修改更新有两种方法

1)save

修改模型类对象的属性,然后执行save()方法

hero = HeroInfo.objects.get(hname='猪八戒')
hero.hname = '猪悟能'
hero.save()

2)update

使用模型类.objects.filter().update(),会返回受影响的行数

HeroInfo.objects.filter(hname='沙悟净').update(hname='沙僧')
更新对象 update(), update_or_create() 更新,更新或创建

三、查询

3.1 基本查询

get 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。

all 查询多个结果。

count 查询结果数量。

>>> BookInfo.objects.all()
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 笑傲江湖>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>
>>> book = BookInfo.objects.get(btitle='西游记')
>>> book.id
5

>>> BookInfo.objects.get(id=3)
<BookInfo: 笑傲江湖>
>>> BookInfo.objects.get(pk=3)
<BookInfo: 笑傲江湖>
>>> BookInfo.objects.get(id=100)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/delron/.virtualenv/dj/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/delron/.virtualenv/dj/lib/python3.6/site-packages/django/db/models/query.py", line 380, in get
    self.model._meta.object_name
db.models.DoesNotExist: BookInfo matching query does not exist.

>>> BookInfo.objects.count()
6

3.2 过滤查询

实现SQL中的where功能,包括

  • filter 过滤出多个结果
  • exclude 排除掉符合条件剩下的结果
  • get 过滤单一结果

对于过滤条件的使用,上述三个方法相同,故仅以filter进行讲解。
过滤条件的表达语法如下:

属性名称__比较运算符=值
# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线

1)相等

exact:表示判等。

exact:精确匹配,区分大小写。iexact:不区分大小写的精确匹配

例:查询编号为1的图书。

BookInfo.objects.filter(id__exact=1)
可简写为:
BookInfo.objects.filter(id=1)

2)模糊查询

contains:是否包含。

说明:如果要包含%无需转义,直接写即可。

例:查询书名包含’传’的图书。

BookInfo.objects.filter(btitle__contains='传')
startswith、endswith:以指定值开头或结尾。

例:查询书名以’部’结尾的图书

BookInfo.objects.filter(btitle__endswith='部')
以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.

3) 空查询

isnull:是否为null。

例:查询书名不为空的图书。

BookInfo.objects.filter(btitle__isnull=False)

4) 范围查询

in:是否包含在范围内。

例:查询编号为1或3或5的图书

BookInfo.objects.filter(id__in=[1, 3, 5])

5)比较查询

  • gt 大于 (greater then)
  • gte 大于等于 (greater then equal)
  • lt 小于 (less then)
  • lte 小于等于 (less then equal)

例:查询编号大于3的图书

BookInfo.objects.filter(id__gt=3)
不等于的运算符,使用exclude()过滤器。

例:查询编号不等于3的图书

BookInfo.objects.exclude(id=3)
Student.objects.all().exclude(nickname='A同学')

6)逆序

reverse() 方法反向排序QuerySet中返回的元素。第二次调用reverse()将恢复到原有的排序。
Student.objects.all().reverse()

7)查询某字段有多少种类的值

distinct 返回一个在SQL 查询中使用SELECT DISTINCT的新QuerySet。它将去除查询结果中重复的行。
Student.objects.all().distinct()

8)惰性操作

orm内所有的语句操作,都是惰性操作:只会在你真正需要数据的时候才会走数据库,如果你单单只写orm语句是不会走数据库的。这样设计的好处在于减轻数据库的压力。

res = models.Book.objects.values('title')   #普通查询方式 获取到的结果是列表套字典
res1 = models.Book.objects.only('title')   #结果是一个个对象,可以直接点属性获取到属性值
print(res)
print(res1)

only和普通查询的不同就是能直接获取到对象,除了可以获取到上面的title属性值,还可以获取到该对象其他的属性值。但是也有优缺点,看下面的例子。

res1 = models.Book.objects.only('title')
for r in res1:
       print(r.title)  #只走一次数据库查询
       print(r.price)  #每取一次数据就走数据库一次
only总结:当你获取一个不是only括号内指定的字段的时候,不会报错,而是会频繁的走数据库查询
defer与only是相反的
res1 = models.Book.objects.defer('title')
    for r in res1:
        print(r.price)  #不是括号内的字段,只走一次数据库查询
defer总结:defer会将不是括号内的所有的字段信息全部查询出来封装到对象中,一旦你查了了括号内的字段,那么会频繁的走数据库查询

9) union(), intersection(), difference() 并集、交集、差集

p_240 = Course.objects.filter(price__gte=240)
p_260 = Course.objects.filter(price__lte=260)
print(p_240.union(p_260))
print(p_240.intersection(p_260))
print(p_240.difference(p_260))
values

返回一个ValuesQuerySet ——QuerySet 的一个子类,迭代时返回字典而不是模型实例对象。
例如:

>>> Blog.objects.filter(name__startswith='Beatles').values()

[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]
values_list()

返回一个ValuesQuerySet ——QuerySet 的一个子类,迭代时返回元组而不是模型实例对象。

6)日期查询

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。

例:查询1980年发表的图书。

BookInfo.objects.filter(bpub_date__year=1980)

例:查询1980年1月1日后发表的图书。

BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))

7)查询某个字段所有值得种类

模型.objects.filter(...). values_list("字段名", flat=True). distinct(). order_by("字段名")

F对象

之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中。

语法如下:

F(属性名)

例:查询阅读量大于等于评论量的图书。

from django.db.models import F

BookInfo.objects.filter(bread__gte=F('bcomment'))

可以在F对象上使用算数运算。

例:查询阅读量大于2倍评论量的图书。

BookInfo.objects.filter(bread__gt=F('bcomment') * 2)

Q对象

多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字。

例:查询阅读量大于20,并且编号小于3的图书。

BookInfo.objects.filter(bread__gt=20,id__lt=3)
或
BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)

如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符,Q对象被义在django.db.models中。

语法如下:

Q(属性名__运算符=值)

例:查询阅读量大于20的图书,改写为Q对象如下。

from django.db.models import Q

BookInfo.objects.filter(Q(bread__gt=20))

Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。

例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现

BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

Q对象前可以使用~操作符,表示非not。

例:查询编号不等于3的图书。

BookInfo.objects.filter(~Q(pk=3))

聚合函数

使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和,被定义在django.db.models中。

例:查询图书的总阅读量。

from django.db.models import Sum

BookInfo.objects.aggregate(Sum('bread'))

注意aggregate的返回值是一个字典类型,格式如下:

  {'属性名__聚合类小写':值}
  如:{'bread__sum':3}

使用count时一般不使用aggregate()过滤器。

例:查询图书总数。

BookInfo.objects.count()

注意count函数的返回值是一个数字。

annotate() 使用聚合计数、求和、平均数 raw() 执行原生的SQL
print(Course.objects.values('teacher').annotate(vol=Sum('volume')))
print(Course.objects.values('teacher').annotate(pri=Avg('price')))

3.3 排序

使用order_by对结果进行排序

BookInfo.objects.all().order_by('bread')  # 升序
BookInfo.objects.all().order_by('-bread')  # 降序

3.4 关联查询

由一到多的访问语法:

一对应的模型类对象.多对应的模型类名小写_set 例:

b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()

由多到一的访问语法:

多对应的模型类对象.多对应的模型类中的关系类属性名 例:

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

访问一一对应的模型类关联对象的id语法:

多对应的模型类对象.关联类属性_id

例:

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

关联过滤查询

由多模型类条件查询一模型类数据:

语法如下:

关联模型类名小写__属性名__条件运算符=值
注意:如果没有"__运算符"部分,表示等于。

例:

查询图书,要求图书英雄为"孙悟空"

BookInfo.objects.filter(heroinfo__hname='孙悟空')

查询图书,要求图书中英雄的描述包含"八"

BookInfo.objects.filter(heroinfo__hcomment__contains='八')
由一模型类条件查询多模型类数据:

语法如下:

一模型类关联属性名__一模型类属性名__条件运算符=值
注意:如果没有"__运算符"部分,表示等于。

例:

查询书名为“天龙八部”的所有英雄。

HeroInfo.objects.filter(hbook__btitle='天龙八部')

查询图书阅读量大于30的所有英雄

HeroInfo.objects.filter(hbook__bread__gt=30)

连表操作之使用函数:select_related与prefetch_related

select_related帮你直接连表操作,查询数据,括号内只能放外键字段
res1 = models.Book.objects.select_related('publish')   #连接book表和publish表
for r in res1:
        print(r.publish.name)

总结:select_related:会将括号内的外键字段所关联的那张表直接全部拿过来(也可以一次性拿多张表)跟当前表拼接操作,从而降低你跨表查询,数据库的压力。

注意:select_related括号内只能放外键字段(一对一和一对多)

res = models.Book.objects.all().select_related('外键字段1__外键字段2__外键字段3__外键字段4')
prefetch_related不主动连表
res2 = models.Book.objects.prefetch_related('publish')
for r in res2:
        print(r.publish.name)

不主动连表操作(但是内部给你的感觉像是连表操作了)而是将book表中的publish全部拿出来,再取publish表中将id对应的所有的数据取出,括号内有几个外键字段,就会走几次数据库查询操作。

其他函数

first(), last(), latest(), earliest() 第一个、最后一个、最新一个、最早一个

四、 删除

删除有两种方法

1)模型类对象delete

hero = HeroInfo.objects.get(id=13)
hero.delete()

2)模型类.objects.filter().delete()

HeroInfo.objects.filter(id=14).delete()

五、事务

ACID

原子性、一致性、隔离性、持久性

from django.db import transaction
    
with transaction.atomic():
    """数据库操作
    在该代码块中书写的操作 同属于一个事务
    """
    models.Book.objects.create()
    models.Publish.objects.create()
    # 添加书籍和出版社 就是同一个事务 要么一起成功要么一起失败
print('出了 代码块 事务就结束')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django模型是ORM(Object Relational Mapping)的实现,它允许你通过Python代码来操作数据库,而不必手动编写SQL语句。下面是一些常见的Django模型操作: 1. 定义模型models.py文件中,定义一个继承自django.db.models.Model的类作为模型。在该类中定义属性,每个属性都是一个字段,可以是CharField、IntegerField、BooleanField等等。 2. 迁移数据库 运行`python manage.py makemigrations`命令,将模型定义转换为迁移文件。然后运行`python manage.py migrate`命令,将迁移应用到数据库。 3. 创建、查询、更新和删除对象 创建对象的方法是通过模型类的构造函数来实现的,例如`MyModel.objects.create(field1=value1, field2=value2)`。查询对象的方法是通过模型类的Manager对象来实现的,例如`MyModel.objects.filter(field1=value1)`。更新对象的方法是通过查询得到的QuerySet对象调用update函数来实现的,例如`MyModel.objects.filter(field1=value1).update(field2=new_value)`。删除对象的方法是通过查询得到的QuerySet对象调用delete函数来实现的,例如`MyModel.objects.filter(field1=value1).delete()`。 4. 关联查询 在模型中定义外键或多对多关系字段,然后可以使用ORM进行关联查询。例如,如果一个模型有一个外键字段指向另一个模型,那么可以使用`my_model.related_field`来获取该关联对象。 5. 聚合和分组查询 使用ORM可以很方便地进行聚合和分组查询。例如,可以使用`MyModel.objects.aggregate(Sum('field'))`来计算某个字段的总和,使用`MyModel.objects.annotate(count=Count('field')).filter(count__gt=10)`来查询某个字段的值大于10的数据。 以上是Django模型操作的一些基本方法,还有很多高级用法可以去官方文档中了解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值