django 学习三

数据库

前言

在django 1.6.x之前,有三种方法将模型更改同步到数据库中:
第一种: 使用 python manage.py syncdb 指令,这个指令只能用于新建新的模型时同步数据库,模型的修改或删除则不能同步到数据库。
第二种: 使用 python manage.py sql appname 指令,手动到数据库执行SQL,这样可以将模型的修改或删除同步到数据库,但是非常容易出错。
第三种:
(1)pip install South 。
(2)把South加入到settings.py中的INSTALLED_APPS中。
(3)使用 python manage.py syncdb 指令来创建。south_migrationhistory表,用来记录数据表更改的历史记录。
(4)使用 python manage.py convert_to_south blog 指令将之前建好的app blog使用South来管理。
(5)使用 python manage.py schemamigration blog --auto 指令,检测blog的模型的修改。
(6)最后,使用 python manage.py migrate 指令,将更改写入数据库中。
注:
(1)如果在blog这个app之前就创建过相关的表,使用 python manage.py migrate blog --fake 指令,而不要使用 python manage.py migrate blog 指令。
而在django 1.7.x及之后的版本,集成了South的功能。使用:
python manage.py makemigrations 指令和
python manage.py migrate 指令会对我们的models.py进行检测,自动发现需要更改的,应用到数据库中。
(2)South有一个好处是可以随时恢复到之前的一个版本。
使用 python manage.py migrate blog 0001 指令,0001指的是0001_initial。

实验

django模型是与数据库相关的,与数据库相关的代码一般写在models.py中。django支持sqlite3、MySQL等数据库,只需要在settings.py中配置即可,不需要更改models.py中的代码,丰富的API极大的方便了使用。
1.新建项目和应用
在这里插入图片描述
2.设置settings.py
在这里插入图片描述
3.修改learn_models\people\models.py
在这里插入图片描述
注意:__str__方法会返回一个对象的描述信息,这样以后查找的时候能够显示对象的信息。
4.创建数据表
默认使用的数据库是sqlite3,无需配置。
(1)使用 python manage.py makemigrations 指令,注意此时数据库还没真正变化,只是生成了描述数据库变化的文件。
在这里插入图片描述
文件内容如下:
在这里插入图片描述
(2)使用指令 python manage.py migrate 指令,将一系列变化应用到了数据库中。
在这里插入图片描述
5.使用django提供的QuerySet API
QuerySet 是从数据库查询出来的结果的集合。
在命令行输入 python manage.py shell 指令启动交互解释器。
(1)新建用户
在这里插入图片描述
(2)查询用户
在这里插入图片描述

补充

1.新建对象
(1)Person.objects.create(name=“name”,age=age)
(2)p=Person(name=“name”,age=age) p.save()
(3)p=Person(name=“name”) p.age=age p.save()
(4)Person.objects.get_or_create(name=“name”,age=age) 这种方法可以防止重复,速度相对会慢。返回一个元组,第一个为Person对象,第二个为True或False,新建时返回的是True,已经存在时返回False。
在这里插入图片描述
2.查询数量
Person.objects.count()
3.获取对象
(1)Person.objects.all()
(2)Person.objects.all()[:10] 切片操作,获取十个人,不支持负索引,切片可以节约内存。
(3)Person.objects.get(name=“name”)
get是用来获取一个对象的,如果需要获取满足条件的一些人,就要用到filter
(4)Person.objects.filter(name=“abc”)
=Person.objects.filter(name_exact=“abc”) 名称严格等于“abc”的人
(5)Person.objects.filter(name_iexact=“abc”) 名称为“abc”但不区分大小写
(6)Person.objects.filter(name_contains=“abc”) 名称中包含“abc”的人
(7)Person.objects.filter(name_icontains=“abc”) 名称中包含“abc”但不区分大小写
(8)Person.objects.filter(name_regex="^abc") 正则表达式查询
(9)Person.objects.filter(name_iregex="^abc") 正则表达式查询,不区分大小写
exclude为排除某条件的
(9)Person.objects.exclude(name_contains=“abc”) 排除名称有“abc”的人
(10)Person.objects.filter(name_contains=“abc”).exclude(age=21) 找出名称有“abc”,但是排除年龄是21岁的
4.更新内容
(1)批量更新
Person.objects.filter(name=“abc”).update(name=“def”) 名称为“abc”的人都改为“def”的人
Person.objects.all().delete() 删除所有的Person记录
(2)单个更新
p=Person.objects.get(name=“abc”)
p.name=“def”
p.email=“def@163.com”
p.save() (不要忘记保存)
5.删除符合条件的结果
Person.objects.filter(name=“abc”).delete() 删除名称为“abc”的人
6.QuerySet基础
(1)QuerySet的迭代
pp=Person.objects.all()
for p in pp:
print§
(2)QuerySet 可以用pickle序列化到硬盘再读取出来
import pickle
query=pickle.loads(s)
p=Person.objects.all()
p.query=query
(3)QuerySet 查询结果排序
Person.objects.all().order_by(“name”)
Person.objects.all().order_by("-name") 倒序排序
(4)QuerySet 支持链式查询
Person.objects.filter(name=“abc”).filter(age=21)
Person.objects.filter(name=“abc”).exclude(age=21)
(5)QuerySet 不支持负索引
Person.objects.all()[:10] 成功
Person.objects.all()[-10:] 失败
可以使用reverse()解决:
Person.objects.all().reverse()[:2] 最后两条
Person.objects.all().reverse()[0] 最后一条
或使用order_by加负号:
Person.objects.order_by("-id")[:20] id最大的20条
(6)QuerySet 去重
QuerySet一般不会重复,但跨越多张表检索后,结果并到一起,可能会出来重复的值。
q1=Person.objects.filter(lable_name=“a”)
q2=Person.objects.filter(reaction_name=“A+B >> C”)
q3=Person.objects.filter(inputer_name=“def”)
q=q1 | q2 | q3
q=q.distinct()
7.QuerySet进阶
(1)查看QuerySet执行的SQL
print(str(Person.objects.all().query))
(2)values_list获取元组形式结果
p=Person.objects.values_list(“name”,“qq”)
p
list§
Person.objects.filter(name=“abc”).values_list(“name”,flat=True) 只需要一个字段,使用flat
(3)values获取字典形式的结果
Person.objects.values(“name”,“qq”)
list(Person.objects.values(“name”,“qq”))
注意:
(1)values_list和values返回的并不是真正的列表或字典,也是queryset,它们是惰性评估的,就是用的时候才真正的去数据库查。
(2)如果查询后没有使用,在数据库更新后再使用,得到的是新内容。如果想要数据库更新后不要变,可以list一下。
(4)extra实现别名、条件、排序等
这里主要看一下别名:
p=Person.objects.all().extra(select={‘people_name’:‘name’})
这样一来,执行p[0].people_name=p[0].name
确认一下:
Person.objects.all().extra
(select={‘people_name’:‘name’}).query.str()
如果我们只想其中一个能用,可以用defer排除掉原来的name:
Person.objects.all().extra(select={‘people_name’:‘name’}).defer(‘name’).query.str()
在这里插入图片描述
(5)annotate聚合 计数、求和、平均数等
计数:
from django.db.models import Count
Article.objects.all().values(‘author_id’).annotate(num_count=Count(‘author’)).values(‘author_id’,‘num_count’)
求和:
from django.db.models import Sum
Article.objects.values(‘author_name’).annotate(sum_score=Sum(‘score’)).values(‘author_name’,‘sum_score’)
平均数:
from django.db.models import Avg
Article.objects.values(‘author_id’).annotate(avg_score=Avg(‘score’)).values(‘author_id’,‘avg_score’)
(6)select_related优化一对一、多对一查询
from blog.models import *
articles=Article.objects.all().select_related(‘author’)[:10]
a1=articles[0] 取第一篇
(7)prefetch_related优化一对多、多对多查询
prefetch_related是通过再执行一条额外的SQL语句,然后用python将两次SQL查询的内容关联到一起。
articles=Article.objects.all().prefetch_related(‘tags’)[:10]
articles
(8)defer排除不需要的字段
Person.objects.all().defer(‘content’)
(9)only仅选择需要的字段
Person.objects.all().only(‘name’)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值