django 表操作
添加表纪录
# Create your models here.
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
state = models.BooleanField()
pub_date = models.DateField()
price = models.DecimalField(max_digits=8, decimal_places=2)
publish = models.CharField(max_length=32)
方式1
book_obj = models.Book(title='python web',price=29, publish='北京出版社',pub_date="2012-12-12")
book_obj.save()
方式2
book_obj = models.Book.objects.create(title="java红宝书", state=True, price=100, publish="苹果出版社", pub_date="2012-12-12")
删除表纪录
删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:
model_obj.delete()
按条件删除
ret = models.Book.objects.all().filter(price__in=[100, 88]).delete()
级联删除
在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField() def __str__(self): # __unicode__ on Python 2
return self.name class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField() def __str__(self): # __unicode__ on Python 2
return self.name class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
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): # __unicode__ on Python 2
return self.headline
delete
b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()
要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:
Entry.objects.all().delete()
如果不想级联删除,可以设置为:
blog = models.ForeignKey(Blog, on_delete=models.SET_NULL, blank=True, null=True)
删除语句
Blog.objects.all().filter(name='python_qq').delete()
修改表纪录
Book.objects.filter(title__startswith="py").update(price=120)
update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。
查询表记录
查询API
1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
如果符合筛选条件的对象超过一个或者没有都会抛出错误。 <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <5> order_by(*field): 对查询结果排序 <6> reverse(): 对查询结果反向排序 <8> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 <9> first(): 返回第一条记录 <10> last(): 返回最后一条记录 <11> exists(): 如果QuerySet包含数据,就返回True,否则返回False <12> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
model的实例化对象,而是一个可迭代的字典序列
<13> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <14> distinct(): 从返回结果中剔除重复纪录
基于双下划线的模糊查询
Book.objects.filter(price__in=[100,200,300])
Book.objects.filter(price__gt=100)
Book.objects.filter(price__lt=100)
Book.objects.filter(price__range=[100,200])
Book.objects.filter(title__contains="python")
Book.objects.filter(title__icontains="python")
Book.objects.filter(title__startswith="py")
Book.objects.filter(pub_date__year=2012)
Entry.objects.get(headline__contains='Lennon')
contains:
表示包含的意思!大小写敏感!
icontains:
contains的大小写不敏感模式。
startswith和endswith
以什么开头和以什么结尾。大小写敏感!
istartswith和iendswith
是不区分大小写的模式。
查询操作练习
# 1
# 查询老男孩出版社出版过的价格大于200的书籍 book_list = models.Book.objects.filter(price__gt=200, publish='老男孩出版社')
print(book_list)
# 2
# 查询2017年8月出版的所有以py开头的书籍名称
book_list = models.Book.objects.filter(title__startswith='py', pub_date__year=2017,pub_date__month=8)
print(book_list)
# 3
# 查询价格为50, 100
# 或者150的所有书籍名称及其出版社名称
book_list = models.Book.objects.filter(price__in=[50, 100,150]).values_list('publish','title')
print(book_list)
# 4
# 查询价格在100到200之间的所有书籍名称及其价格
book_list = models.Book.objects.filter(price__range=[100,200]).values_list('title','price')
print(book_list)
# 5
# 查询所有人民出版社出版的书籍的价格(从高到低排序,去重)
book_list = models.Book.objects.filter(publish='人民出版社').values_list('price').distinct().order_by('-price')
print(book_list)
多表操作
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField() # 与AuthorDetail建立一对一的关系
authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=64) class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
authors=models.ManyToManyField(to='Author',)
多对多添加方式
book_obj = Book.objects.filter(nid=1).first()
alex = Author.objects.create(name='alex', age='', authorDetail_id=1)
egon = Author.objects.create(name='egon', age='', authorDetail_id=2)
#
# # 多对多添加方式
book_obj.authors.add(alex, egon)
跨表查询
# 1.基于对象的查询(子查询)
"""
A-B
关联属性在A表 正向查询 A---------B
反向查询 B---------A
"""
"""
一对多
""" # 正向查询查字段
# 查询书名为红楼梦的出版社名字
book_obj = Book.objects.filter(title='红楼梦').first()
print(book_obj.publish.name) # 查询关联的出版社对象 # 反向查询查表名_set.all
# 查询书名为人民出版社的书名
publish_obj = Publish.objects.filter(name='人民出版社').first()
print(publish_obj.book_set.all()) """
多对多 """
# 正向查询查字段
# 查询书名为红楼梦的作者名字
book_obj = Book.objects.filter(title='红楼梦').first()
print(book_obj.authors.all()) # 查询关联的作者对象 # 反向查询查表名_set.all
# 查询alex写的书名
author_obj = Author.objects.filter(name='alex').first()
print(author_obj.book_set.all()) """
一对一查询
"""
"""
A - B
关联属性在A表 正向查询
A - --------B
反向查询
B - --------A """ # 正向查询查字段
# 查询alex作者电话
author_obj = Author.objects.filter(name='alex').first()
print(author_obj.authorDetail.telephone) # 查询关联的作者细节对象 # 反向查询查表名
# 查询电话111的作者
authorDetail_obj = AuthorDetail.objects.filter(telephone='').first()
print(authorDetail_obj.author.name, authorDetail_obj.author.age)
# 2.基于双下划线的查询(join)
# 正向查询查字段,反向查询查表名告诉orm join # 查询书名为红楼梦的出版社名字(一对多)
"""
sql:
select app3_publish.name from app3_book inner join app3_publish
on app3_book.publish_id = app3_publish.nid where app3_book.title='红楼梦' """
# 方式一
# <QuerySet [{'publish__name': '人民出版社'}]>
print(Book.objects.filter(title='红楼梦').values("publish__name")) # 方式二
print(Publish.objects.filter(book__title='红楼梦').values(
"name")) # <QuerySet [{'publish__name': '人民出版社'}]> # 查询书名为红楼梦的作者名字(多对多)
"""
sql:
select name from app3_author inner join app3_book_authors on app3_author.nid = app3_book_authors.author_id
inner join app3_book on app3_book.nid = app3_book_authors.book_id
"""
# 方式一
# <QuerySet [{'authors__name': 'alex,egon'}]>
print(Book.objects.filter(title='红楼梦').values("authors__name")) # 方式二
print(Author.objects.filter(book__title='红楼梦').values("name")) # 查询alex作者电话
print(Author.objects.filter(name='alex').values("authorDetail__telephone")) print(AuthorDetail.objects.filter(author__name='alex').values("telephone")) # 进阶练习
# 查询电话111作者出版过所有书籍及书籍出版社的名称 # 方式1
print(
Book.objects.filter(
authors__authorDetail__telephone__startswith='11').values(
"title",
"publish__name")) # 方式2
print(
Author.objects.filter(
authorDetail__telephone__startswith='11').values(
"book__title",
"book__publish__name"))
聚合查询
from django.db.models import Count, Max, Min, Avg print(
Book.objects.all().aggregate(
avg_price=Avg("price"),
max_price=Max('price'),
min_price=Min('price'))) # 返回字典 # 单表分组查询
# 查询每一个省以及对应的员工数 # emp:
print(Emp.objects.values("province").annotate(cnt=Count("id"))) # 多表分组查询
# 查询出版社的名称及出版书籍的个数
ret = Publish.objects.values("nid").annotate(cnt=Count("book__title"))
print(ret) ret = Publish.objects.values("name").annotate(cnt=Count("book__title"))
print(ret) ret = Publish.objects.values("name").annotate(
cnt=Count("book__title")).values(
"name", "cnt")
print(ret) # 查询每一个作者的名字以及出版书籍的最高价格
ret = Author.objects.values("pk").annotate(
max_price=Max("book__price")).values(
"name", "max_price")
print(ret) # 查询每一个书籍的名称及对应的作者个数
ret = Book.objects.values("pk").annotate(
cnt=Count("authors__nid")).values(
"title", "cnt")
print(ret) # 统计每一本以py开头的书籍的作者个数:
ret = Book.objects.filter(
title__startswith="py").values("pk").annotate(
cnt=Count("authors__nid")).values(
"title",
"cnt")
print(ret) # (4)统计不止一个作者的图书
ret = Book.objects.values("pk").annotate(
cnt=Count("authors__nid")).filter(
cnt__gt=1).values(
"title",
"cnt")
print(ret) # F查询Q查询
from django.db.models import F, Q
# 统计书的评论数大于读过数
ret = Book.objects.filter(comment_num__lt=F("read_num"))
print(ret) Book.objects.all().update(price=F("price") + 10) ret = Book.objects.filter(Q(title='红楼梦') | Q(price__gt=100))
print(ret) ret = Book.objects.filter(~Q(title='红楼梦') | Q(price__gt=100))
print(ret)
操作API
get() | 获取单个对象 |
create() | 创建对象,无需save() |
get_or_create() | 查询对象,如果没有找到就新建对象 |
update_or_create() | 更新对象,如果没有找到就创建对象 |
bulk_create() |
批量创建对象 |
count() | 统计对象的个数 |
in_bulk() |
根据主键值的列表,批量返回对象 |
iterator() |
获取包含对象的迭代器 |
latest() | 获取最近的对象 |
earliest() | 获取最早的对象 |
first() | 获取第一个对象 |
last() | 获取最后一个对象 |
aggregate() | 聚合操作 |
exists() | 判断queryset中是否有对象 |
update() | 批量更新对象 |
delete() | 批量删除对象 |
get()
get(**kwargs)
返回按照查询参数匹配到的单个对象,参数的格式应该符合Field lookups的要求。
如果匹配到的对象个数不只一个的话,触发MultipleObjectsReturned异常
如果根据给出的参数匹配不到对象的话,触发DoesNotExist异常。例如:
bulk_create()
bulk_create(objs, batch_size=None)
以高效的方式(通常只有1个查询,无论有多少对象)将提供的对象列表插入到数据库中:
Entry.objects.bulk_create([
... Entry(headline='This is a test'),
... Entry(headline='This is only a test'),
... ])
注意事项:
- 不会调用模型的save()方法,并且不会发送
pre_save
和post_save
信号。 - 不适用于多表继承场景中的子模型。
- 如果模型的主键是AutoField,则不会像save()那样检索并设置主键属性,除非数据库后端支持。
- 不适用于多对多关系。
batch_size
参数控制在单个查询中创建的对象数。
count()
返回在数据库中对应的QuerySet对象的个数。count()永远不会引发异常。
latest(field_name=None)
使用日期字段field_name,按日期返回最新对象。
下例根据Entry的'pub_date'字段返回最新发布的entry:
Entry.objects.latest('pub_date')
exists()
如果QuerySet包含任何结果,则返回True,否则返回False。
查找具有唯一性字段(例如primary_key)的模型是否在一个QuerySet中的最高效的方法是:
entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
print("Entry contained in queryset")
它将比下面的方法快很多,这个方法要求对QuerySet求值并迭代整个QuerySet:
if entry in some_queryset:
print("Entry contained in QuerySet")
若要查找一个QuerySet是否包含任何元素:
if some_queryset.exists():
print("There is at least one object in some_queryset")
将快于:
if some_queryset:
print("There is at least one object in some_queryset")
查询参数及聚合函数
http://www.liujiangblog.com/course/django/132
django 表操作的更多相关文章
- python——Django(ORM连表操作)
千呼万唤始出来~~~当当当,终于系统讲了django的ORM操作啦!!!这里记录的是django操作数据库表一对多.多对多的表创建及操作.对于操作,我们只记录连表相关的内容,介绍增加数据和查找数据,因 ...
- Django ORM多表操作
多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对 ...
- Django学习笔记(7)——单表操作和多表操作
单表操作 1,创建模型 创建名为book的APP,在book下的models.py中创建模型: from django.db import models # Create your models he ...
- web框架开发-Django模型层(1)之ORM简介和单表操作
ORM简介 不需要使用pymysql的硬编码方式,在py文件中写sql语句,提供更简便,更上层的接口,数据迁移方便(有转换的引擎,方便迁移到不同的数据库平台)…(很多优点),缺点,因为多了转换环节,效 ...
- Django 数据库查询集合(双下划线连表操作)
Django是一款优秀的web框架,有着自己的ORM数据库模型.在项目中一直使用django数据库,写一篇文章专门记录一下数据库操作.略写django工程创建过程,详写查询过程.可以和sqlalche ...
- Django模型层-多表操作
多表操作 一.创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是 ...
- Django模型层-单表操作
ORM介绍 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...
- django——模型层之多表操作
django的多表操作 1.使用场景 在实际生产过程多,我们面对的数据纷繁复杂,此时就需要良好的数据结构设计,多表之间的约束关系为我们提供了数据管理以及查询的便利.在MYsql中我们利用外键(fore ...
- Django之django模型层二多表操作
一 创建模型 表和表之间的关系 一对一.多对一.多对多 ,用book表和publish表自己来想想关系,想想里面的操作,加外键约束和不加外键约束的区别,一对一的外键约束是在一对多的约束上加上唯一约束. ...
随机推荐
- robotframework+Python3.7 接口自动化测试
具体的测试用例,password,channel,resultCode传给接口描述 集成了一些常见的测试接口方法 1. Get请求下,
- 逆向破解之160个CrackMe —— 008-009
CrackMe —— 008 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...
- ThinkPHP模板之一
这个东东,就得多练多写,无它法. 1,Application\Home\Controller\IndexController.class.php <?php namespace Home\Con ...
- 2019年牛客多校第一场 I题Points Division 线段树+DP
题目链接 传送门 题意 给你\(n\)个点,每个点的坐标为\((x_i,y_i)\),有两个权值\(a_i,b_i\). 现在要你将它分成\(\mathbb{A},\mathbb{B}\)两部分,使得 ...
- BZOJ1485: [HNOI2009]有趣的数列(卡特兰数+快速幂)
题目链接 传送门 题面 思路 打表可以发现前六项分别为1,2,5,12,42,132,加上\(n=0\)时的1构成了卡特兰数的前几项. 看别人的题解说把每一个数扫一遍,奇数项当成入栈,偶数项当成出栈, ...
- 对象输入输出流ObjectInputStream、ObjectOutputStream(对象的序列化与反序列化)
如题 所有关联的类需要继承Serializable 接口 文件为空,直接反序列化为发生错误; 毕竟对象为null , 序列化到文件里不是空空的! 以下笔记的原文连接: https://www.cnbl ...
- 修改cloud image密码
安装libguestfs-tools yum -y install libguestfs-tools.noarch 设置固定密码 virt-customize -a CentOS-7-x86_64-G ...
- PS——使用切片工具切出透明图片
前言 最近有点烦,不说话~ 步骤 首先要保证您的格式为PSD且底色为透明 参考线 标出参考线,方便后面划分 切图 保存 效果
- select 与 I/O多路转接
参考博客:http://blog.sina.com.cn/s/blog_607072980102uxcw.html I/0多路转接: 描述符表示某个I/O.构造一张有关描述符的数据表,调用select ...
- centos7.2(二)搭建lamp(Apache+PHP+Mysql环境)教程
开始安装前,看说明. 说明0 查看服务器是否能被ssh登陆 http://tool.chinaz.com/port/ 如果显示关闭,说明被大陆封闭了,删除服务器重新建立一个. 说明1:Centos7 ...