表结构
-
class Book(models.Model): nid = models.AutoField(primary_key=True) # 自增id(可以不写,默认会有自增id) title = models.CharField(max_length=32) publishDdata = models.DateField() # 出版日期 price = models.DecimalField(max_digits=5, decimal_places=2) # 一共5位,保留两位小数 #一个出版社有多本书,关联字段要写在多的一方 # 不用命名为publish_id,因为django为我们自动就加上了_id publish = models.ForeignKey("Publish") #foreignkey(表名)建立的一对多关系 # publish是实例对象关联的出版社对象 authorlist = models.ManyToManyField("Author") #建立的多对多的关系 def __str__(self): #__str__方法使用来吧对象转换成字符串的,你返回啥内容就打印啥 return self.title class Publish(models.Model): #不写id的时候数据库会自动给你增加自增id name =models.CharField(max_length=32) addr = models.CharField(max_length=32) def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() class AuthorDeital(models.Model): tel = models.IntegerField() addr = models.CharField(max_length=32) author = models.OneToOneField("Author") #建立的一对一的关系
-
建立一对一的关系
-
OneToOneField()
-
就是foreignkey+unique,只不过不需要我们自己来写参数了,并且orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为authorDetail_id
-
au=models.OneToOneField("AuthorDetail",on_delete=models.CASCADE)
-
-
建立一对多的关系
-
ForeignKey()
-
publishs=models.ForeignKey(to="Publish",on_delete=models.CASCADE,)
-
-
建立多对多关系
-
ManyToManyField可以建在两个模型中的任意一个,自动创建第三张
-
-
注意
-
临时添加的字段,首先得考虑之前的数据有没有,设置一个默认值
-
1、 表的名称
myapp_modelName
,是根据 模型中的元数据自动生成的,也可以覆写为别的名称2、
id
字段是自动添加的3、对于外键字段,Django 会在字段名上添加
"_id"
来创建数据库中的列名4、这个例子中的
CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。5、定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py
所在应用的名称。6、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
-
logging-SQL语句
-
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
增删改查
1,增
-
一对多添加
-
# 一对多的添加 # 方式一:如果是这样直接指定publish_id字段去添加值,前提是你的主表里面必须有数据 # 主表:没有被关联的(因为book表是要依赖于publish这个表的)也就是publish表 # 子表:关联的表 models.Book.objects.create(title="追风筝的人",publishDdata="2015-5-8",price="111",publish_id=1) # 方式二:推荐 pub_obj = models.Publish.objects.filter(name="人民出版社")[0] print(pub_obj) models.Book.objects.create(title = "简爱",publishDdata="2000-6-6",price="222",publish=pub_obj) # 方式三:save pubObj= models.Publish.objects.get(name="人民出版社") #只有一个的时候用get,拿到的直接就是一个对象 bookObj = models.Book(title = "真正的勇士",publishDdata="2015-9-9",price="50",publish=pubObj) bookObj.save()
-
-
多对多添加的两种方式
-
# 多对多的添加的两种方式 # 方式一: # 先创建一本书: pub_obj=models.Publish.objects.filter(name="江南出版社").first() book_obj = models.Book.objects.create(title="醉玲珑",publishDdata="2015-4-10",price="222",publish=pub_obj) # #通过作者的名字django默认找到id haiyan_obj = models.Author.objects.filter(name="haiyan")[0] egon_obj = models.Author.objects.filter(name="egon")[0] xiaoxiao_obj = models.Author.objects.filter(name="xiaoxiao")[0] # 绑定多对多的关系、 book_obj.authorlist.add(haiyan_obj, egon_obj, xiaoxiao_obj) # 方式二=========,查出所有的作者 pub_obj = models.Publish.objects.filter(name="江南出版社").first() book_obj = models.Book.objects.create(title="醉玲珑", publishDdata="2015-4-10", price="222", publish=pub_obj) authers = models.Author.objects.all() # #绑定多对多关系 book_obj.authorlist.add(*authers)
-
2,删
-
remove:将某个特定的对象从被关联对象集合中去除,即解除关联关系
-
# 解除多对多的关系(remove) book_obj=models.Book.objects.filter(title="醉玲珑").last() #找到书对象 authers=models.Author.objects.filter(id__lt=3) #找到符合条件的作者对象 book_obj.authorlist.remove(*authers) #因为清除的是多条,得加个*
-
-
清除绑定:clear
-
清空被关联对象集合
-
# 清除关系方法(clear) book_obj= models.Book.objects.filter(title="红楼梦") for book_obj_item in book_obj:#把所有红楼梦的都给清空了 book_obj_item.authorlist.clear()
-
-
两者区别:
- remove:先将要清除的数据筛选出来,然后移除
- clear:不用查,直接就把数据都清空了。
- 各有应用场景
3,改
- 改和查一样
4,查
-
一对一查询记录
- 正向查询:按字段属性
- 反向查询:按表名,一对一用不到_set
-
一对多查询记录
- 正向查询:按字段属性
- 反向查询:按表名_set
-
多对多查询记录
- 正向查询:按字段属性
- 反向查询:按表名__set
-
related_name:别名
-
你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Article model 中做一下更改: publish = ForeignKey(Blog, related_name='bookList'),那么接下来就会如我们看到这般:
# 查询 人民出版社出版过的所有书籍 publish=Publish.objects.get(name="人民出版社") book_list=publish.bookList.all() # 与人民出版社关联的所有书籍对象集合
-
双下划线的跨表查询
- 正向查询:按字段属性
- 反向查询:按表名____
- 先筛选,然后通过跨表查值的方法
聚合查询
-
aggregate(*args, **kwargs),只对一个组进行聚合
-
SQL原生语句中的聚合为group by
-
aggregate()是QuerySet的一个终止子句,也就是不在返回一个QuerySet集合,他返回一些键值对
-
from django.db.models import Avg, Sum, Count, Max, Min #查询所有图书的平均价格 ret = models.Book.objects.all().aggregrate(Avg("price")) print(ret)
分组查询
-
annotate():为QuerySet中每一个对象都生成一个独立的汇总值,是对分组完之后的结果进行聚合
-
from django.db.models import Count #统计每一本书的作者个数 方式一: ret = models.Book.objects.all().annotate(authorNum = Count("authorlist__name")).values("authorNum") #values中的内容就是要分组的内容, #统计不止一个作者的书 ret = models.Book.objects.annotate(num_authors=Count("authorlist__name")).filter(num__gt=1).values("title","num_authors") #统计各个作者出书的总价格 ret = models.Author.objects.all().annotate(pricrSum = Sum("book__price")).values("name","priceSum")
-
总结
- 按什么分组就以它作为基表
- values在前,表示group by,也可以省略不写,默认为pk =====在后,表示取值,
- filter在前,表示where条件====在后表示having
- 在前与在后比较的是annotate()
F查询和Q查询
1,F查询
-
Django内置提供的F(),可以在查询中引用字段,来比较同一个model实例中两个不同字段的值
-
from django.db.models import F 前面的filter里面都是用字段与一个常量比较, 如果要比较的是两个字段呢,就需要借助F函数了 不只是filter, 其他地方也可以用, 比如update 用的时候将F()包裹某个字段就能拿到它的值了 现将Book表插入阅读数与评论数两个字段后执行数据库迁移命令 eg: 查询评论数大于阅读数的书 Book.objects.all().filter(commit_num__gt=F('read_num')) eg: 把所有书的评论数加1 Book.objects.all().update(commit_num=F('commit_num')+1) eg: 把python这本书的阅读数减5 Book.objects.all().filter(name='python').update(reat_num=F('reat_num') - 5)
Q查询
-
filte() 筛选中的关键字参数都是一起进行’AND’的,如果需要执行跟复杂的查询,例如or语句,则需要使用Q对象
-
&————与
-
|—————或
-
~————非
-
将两个条件分别用Q()包裹,中间放与或非符号
-
'''
filter里面放多个条件时我们用逗号隔开他默认是and的关系Q函数是为了表示 与& , 或|, 非~ 的
将两个条件分别用Q()包裹中间放与或非符号
导入Q函数
from django.db.models import Qeg: 查询作者名字是江南或者名字是egon的书的书名和作者
Book.objects.all().filter(Q(authors__name='江南') | Q(authors__name='egon')).values('name','authors__name')eg: 查询作者不是江南的书
Book.objects.filter(~Q(authors__name='江南'))
'''