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 = {
‘version‘: 1,
‘disable_existing_loggers‘: False,
‘handlers‘: {
‘console‘:{
‘level‘:‘DEBUG‘,
‘class‘:‘logging.StreamHandler‘,
},
},
‘loggers‘: {
‘django.db.backends‘: {
‘handlers‘: [‘console‘],
‘propagate‘: True,
‘level‘:‘DEBUG‘,
},
}
}
一对多添加
# 一对多的添加
# 方式一:如果是这样直接指定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)
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()
两者区别:
一对一查询记录
一对多查询记录
多对多查询记录
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")
总结
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)
filte() 筛选中的关键字参数都是一起进行’AND’的,如果需要执行跟复杂的查询,例如or语句,则需要使用Q对象
&————与
|—————或
~————非
将两个条件分别用Q()包裹,中间放与或非符号
‘‘‘ filter里面放多个条件时我们用逗号隔开他默认是and的关系
Q函数是为了表示 与& , 或|, 非~ 的
将两个条件分别用Q()包裹中间放与或非符号
导入Q函数 from django.db.models import Q
eg: 查询作者名字是江南或者名字是egon的书的书名和作者 Book.objects.all().filter(Q(authors__name=‘江南‘) | Q(authors__name=‘egon‘)).values(‘name‘,‘authors__name‘)
eg: 查询作者不是江南的书 Book.objects.filter(~Q(authors__name=‘江南‘)) ‘‘‘
原文:https://www.cnblogs.com/daviddd/p/12050229.html