ORM多表操作
目录
表关系介绍
表与表关系
表与表关系有3种方式
一对一(利用 OneToOneField 产生关联关系)
多对一(利用 ForeignKey 产生关联关系)
多对多(利用 ManyToManyField 产生关联关系)
关联后产生的表是什么样子?
一对1会产生属性_id
默认指向主键 可能是隐藏主键 djamgo1.1默认级联(models. SET NULL解除级联)
一对一
先建立少的一方
from django.db import models
# Create your models here.
class Us(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
bday = models.DateField()
checked = models.BooleanField()
class Uss(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
bday = models.DateField()
gl = models.OneToOneField(to="Us",to_field="id",on_delete=models.CASCADE)
to对应被关联的表 to_field对应被关联的id(不填默认主键) on_delete=models.CASCADE 设置级联更新
被关联表
关联表
多对1
被关联表
关联表
多对多
from django.db import models
# Create your models here.
class Us(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
bday = models.DateField()
checked = models.BooleanField()
class Udud(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
bday = models.DateField()
dszb=models.ManyToManyField('Us')
us表
udud表
第3张表dszb
多表增删改查表数据
创建表代码
from django.db import models
class Author(models.Model):
"""
作者表
"""
name = models.CharField(max_length=32, verbose_name='作者名')
age = models.IntegerField(verbose_name='年龄')
au = models.OneToOneField("AuthorDetail", on_delete=models.CASCADE)
# class Meta: # 不可以用
# db_table = 'app01_author' # 指定表名 不用这个 也没事
# ordering = ['-id'] # 用于排序
# verbose_name = '作者表' # 显示作用
def __str__(self):
return self.name
class AuthorDetail(models.Model):
"""
作者详细信息表
"""
birthday = models.DateField(verbose_name='生日')
telephone = models.CharField(max_length=11, verbose_name='手机号')
addr = models.CharField(max_length=64, verbose_name='地址')
# class Meta: #
# ordering = ['id'] # 用于排序
# verbose_name = '作者详细信息表' # 显示作用
def __str__(self):
return self.telephone + self.addr
class Publish(models.Model):
"""
出版社表
"""
name = models.CharField(max_length=32, verbose_name='出版社名字')
city = models.CharField(max_length=32, verbose_name='出版社城市')
def __str__(self):
return self.name
# class Meta: #
# ordering = ['id'] # 用于排序
# verbose_name = '出版社表' # 显示作用
class Book(models.Model):
"""
书籍表
"""
title = models.CharField(max_length=32, verbose_name='书籍名字')
publishDate = models.DateField(verbose_name='书籍出版日期')
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='书价格')
publishs = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
authors = models.ManyToManyField('Author')
def __str__(self):
return self.title
# class Meta: #
# ordering = ['id'] # 用于排序
# verbose_name = '出版社表' # 显示作用
from django.db import models
# Create your models here.
class Author(models.Model):
"""
作者表
"""
name=models.CharField( max_length=32)
age=models.IntegerField()
# authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
au=models.OneToOneField("AuthorDetail",on_delete=models.CASCADE)
def __str__(self):
return self.name
class AuthorDetail(models.Model):
"""
作者详细信息表
"""
birthday=models.DateField()
telephone=models.CharField(max_length=11)
addr=models.CharField(max_length=64)
# class Meta:
# db_table='authordetail' #指定表名
# ordering = ['-id',]
def __str__(self):
return self.telephone + self.addr
class Publish(models.Model):
"""
出版社表
"""
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
def __str__(self):
return self.name
class Book(models.Model):
"""
书籍表
"""
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
publishs=models.ForeignKey(to="Publish",on_delete=models.CASCADE,)
authors=models.ManyToManyField('Author',)
def __str__(self):
return self.title
多表增加
多表增加 有2种方式 一种是直接利用字段增加 一种是利用找到的mode对象增加
下面是 代码示例
一对一 和 一对多 方法相同
一对一 和 一对多
第一种方式 利用新生成的字段增加
models.Author.objects.create(
name='海狗',
age=59,
au_id=4
)
第2种方式(与id为4的就是一对一关系)ghj
au_obj = models.AuthorDetail.objects.get(id=4)
第一种方式
models.Author.objects.create(
name='海狗',
age=59,
au=au_obj
)
一对多
pub_obj = models.Publish.objects.get(id=3)
models.Book.objects.create(
title='xx2',
price=13,
publishDate='2011-11-12',
# publishs=pub_obj , #类属性作为关键字时,值为model对象
publishs_id=3 # 如果关键字为数据库字段名称,那么值为关联数据的值
)
多对多
第一种
new_obj = models.Book.objects.create(
title='海狗产后护理第二部',
price=0.5,
publishDate='2019-09-29',
publishs_id=2,
)
new_obj.authors.add(3, 5) # #*args **kwargs
new_obj.authors.add(*[3, 5]) # 用的最多,
第2种
ziwen = models.Author.objects.get(id=3)
haigou = models.Author.objects.get(id=5)
new_obj = models.Book.objects.create(
title='海狗产后护理第二部',
price=0.5,
publishDate='2019-09-29',
publishs_id=2,
)
new_obj.authors.add(ziwen, haigou)
删除
一对一 一对多 删除都是找到mode对象delete()就行
多对多就比较特殊 要先找到对象 在点属性 进行修改
一对一
# models.AuthorDetail.objects.filter(id=3).delete()
一对多
models.Publish.objects.filter(id=3).delete()
# 多对多
book_obj = models.Book.objects.get(id=2)
book_obj.authors.clear() # 清除
book_obj.authors.set(['1','5']) # 先清除再添加,相当于修改
改
找到对象直接改
第一种
models.Book.objects.filter(id=5).update(
title='华丽丽',
publishs=ret,
publishs_id=1,
)
第2种
ret = models.Publish.objects.get(id=2)
models.Book.objects.filter(id=5).update(
title='华丽丽',
publishs=ret,
)
跨表查询子查询
查询2种方式 (正向查询,反向查询) 关系属性写在表1,关联到表2,那么通过表1的数据去找表2的数据,叫做正向查询,返过来就是反向查询
正向查询用 属性
反向查询用 表名(小写的)
注意
多对多 反向查询用 表名_set
只要含义多个的可能性都用all全部查询出来 在for循环 得到信息
下面是查询实列
查询实列
# 查询
# 一对一
# 关系属性写在表1,关联到表2,那么通过表1的数据去找表2的数据,叫做正向查询,返过来就是反向查询
# 查询一下王洋的电话号码
# 正向查询 对象.属性
# obj = models.Author.objects.filter(name='王洋').first()
# ph = obj.au.telephone
# print(ph)
# 查一下电话号码为120的作者姓名
# 反向查询 对象.小写的表名
# obj = models.AuthorDetail.objects.filter(telephone=120).first()
# ret = obj.author.name #陈硕
# print(ret)
# 一对多
# 查询一下 海狗的怂逼人生这本书是哪个出版社出版的 正向查询
# obj = models.Book.objects.filter(title='海狗的怂逼人生').first()
# ret = obj.publishs.name
# print(ret) #24期出版社
# 查询一下 24期出版社出版过哪些书
# obj = models.Publish.objects.filter(name='24期出版社').first()
#
# ret = obj.book_set.all() #<QuerySet [<Book: 母猪的产后护理>, <Book: 海狗的怂逼人生>]>
# for i in ret:
# print(i.title)
# 多对多
# 海狗的怂逼人生 是哪些作者写的 -- 正向查询
# obj = models.Book.objects.filter(title='海狗的怂逼人生').first()
# ret = obj.authors.all()
#
# print(ret) #<QuerySet [<Author: 王洋>, <Author: 海狗>]>
# for i in ret:
# print(i.name)
# 查询一下海狗写了哪些书 -- 反向查询
# obj = models.Author.objects.filter(name='海狗').first()
# ret = obj.book_set.all()
# print(ret)
# for i in ret:
# print(i.publishs.name)
# print(i.title)
# return HttpResponse('ok')
基于双下划线的跨表查询(连表查询 join)
正向查询用属性 反向用表名
# 一对一
# 查询一下王洋的电话号码
正向查询
# ret = models.Author.objects.filter(name='王洋').values('au__telephone')
反向查询
# ret = models.AuthorDetail.objects.filter(author__name='王洋').values('telephone')
# print(ret) #<QuerySet [{'au__telephone': '110'}]> #<QuerySet [{'telephone': '110'}]>
#
# 一对多
# 海狗的怂逼人生这本书是哪个出版社出版的
正向查询
# ret = models.Book.objects.filter(title='海狗的怂逼人生').values('publishs__name')
# print(ret) #<QuerySet [{'publishs__name': '24期出版社'}]>
反向查询
# ret = models.Publish.objects.filter(book__title='海狗的怂逼人生').values('name')
# print(ret) #<QuerySet [{'name': '24期出版社'}]>
多对多
# 海狗的怂逼人生 是哪些作者写的 -- 正向查询
# obj = models.Book.objects.filter(title='海狗的怂逼人生').first()
# ret = obj.authors.all()
#
# print(ret) #<QuerySet [<Author: 王洋>, <Author: 海狗>]>
# for i in ret:
# print(i.name)
# 查询一下海狗写了哪些书 -- 反向查询
# obj = models.Author.objects.filter(name='海狗').first()
# ret = obj.book_set.all()
# print(ret)
# for i in ret:
# print(i.publishs.name)
# print(i.title)
分组查询
# 每个出版社出版的书的平均价格
# 用的是publish表的id字段进行分组
# ret = models.Book.objects.values('publishs__id').annotate(a=Avg('price'))
# 用的book表的publishs_id字段进行分组
# ret = models.Book.objects.values('publishs_id').annotate(a=Avg('price'))
# print(ret)
# ret = models.Publish.objects.annotate(a=Avg('book__price')).values('a')
# print(ret) #<QuerySet [{'a': None}, {'a': 71.166667}, {'a': 6.0}]>
聚合查询(求和等)
ret = models.Book.objects.all().aggregate(a=Avg('price'),m=Max('price'))
print(ret)
#{'price__avg': 45.1, 'price__max': Decimal('200.00')} python字典格式,也就是说,聚合查询是orm语句的结束
F查询(同表 字段比较 更新)
from django.db.models import Avg, Sum, Max, Min, Count,F
查询一下评论数大于点赞数的书
# ret = models.Book.objects.filter(comment__gt=F('good'))
# print(ret)
将所有书的价格上调100块
# models.Book.objects.all().update(
# price=F('price')+100
# )
Q查询(与或非)
from django.db.models import Avg, Sum, Max, Min, Count, F,Q
ret = models.Book.objects.filter(Q(id=2)&Q(Q(price__gt=112)|~Q(comment__lte=200)))
print(ret)
admin添加用户
python manage.py createsuperuser
输入用户名:wuchao
邮箱不用输 直接回车
输入密码:必须超过8位,并且别太简单
admin注册
from django.contrib import admin
# Register your models here.
from app01 import models
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)
admin.site.register(models.Book)
admin添加用户
python manage.py createsuperuser
输入用户名:wuchao
邮箱不用输 直接回车
输入密码:必须超过8位,并且别太简单
非学,无以致疑;非问,无以广识