Django - 模型层 - 下
一、多表 sql
单表
多表
多对一 多对多 一对一
===============================================
一对多:
Book
id title price publish_id
1 php 100 1
2 python 200 1
3 go 300 2
Publish
id name email addr
1 人名出版社 @ 北京
2 沙河出版社 @ 沙河
一旦确定是 一对多
怎么建立一对多的关系?---》 关联字段 ,建在‘多’的表中
查询python这本书的出版社的邮箱
(子查询)
select email from Publish where id = (
select publish_id from Book where title = 'python'
)
===============================================
多对多:(彼此一对多)
Book
id title price publish_id
1 php 100 1
2 python 200 1
3 go 300 2
Author
id name age addr
1 alex 34 beijing
2 egon 29 nanjing
Book2Author
id book_id author_id
1 2 1
2 2 2
3 3 2
alex 出版过的书籍名称 (子查询:以一个查询的结果作为下一个查询的条件)
select title from Book where id in (
select book_id from Book2Author where author_id = (
select id from Author where name = 'alex'
)
)
===============================================
一对一:
Author
id name age authordetail_id(unique) (一定要加)
1 alex 34 1
2 egon 29 2
AuthorDetail (这个信息不经常查,为了效率,扩展)
id addr gender tel gf_name
1 beijing male 110 小花
2 nanjing male 911 红花
===============================================
总结:
一旦确定是 一对多
怎么建立一对多的关系?---》 关联字段 ,建在‘多’的表中
一旦确定是 多对多
怎么建立多对多的关系?---》 创建第三张表(关联表): id 和 两个关联字段
一旦确定是 一对一
怎么建立一对一的关系?---》 在两张表中的任意一张表中建立关联字段 + unique
Publish
Book
AuthorDetail
Author
Book2Author
=====================================================
create table publish(
id int primary key auto_increment,
name varchar(20)
);
create table book(
id int primary key auto_increment,
title varchar(20),
price decimal(8,2),
pub_date date,
publish_id int,
foreign key (publish_id) references publish(id)
);
create table authordetail(
id int primary key auto_increment,
tel varchar(20)
);
create table author(
id int primary key auto_increment,
name varchar(20),
age int,
authordetail_id int unique,
foreign key (authordetail_id) references authordetail(id)
);
create table book2author(
id int primary key auto_increment,
book_id int,
author_id int
);
=====================================================
二、创建模型
''' Book Publish Author AuthorDetail Book2Author 会自定生成 Book -- Publish 一对多 Author -- AuthorDetail 一对一 Book -- Author 多对多 Book2Author ''' from django.db import models # 作者详情表 class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() # 一对一 关系 这里会生成一个字段 authordetail_id authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE) 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() # def __str__(self): # 打印的时候 可以打印出name # return self.name class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=8,decimal_places=2) # 一对多 关系 # 这里会生成一个 字段 publish_id publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) ''' publish_id int, foreign key (publish_id) references publish(id) ''' # 多对多 # 这里会生成第三张表 book_authors authors = models.ManyToManyField(to='Author') ''' create table book_authors( id int primary key auto_increment, book_id int, author_id int ); ''' def __str__(self): return self.title # 这里生成第三张表的本质 # django 去写不用我们写 # class Book2Author(models.Model): # nid = models.AutoField(primary_key=True) # book = models.ForeignKey(to='Book') # 默认关联主键 # author = models.ForeignKey(to='Author') ''' 数据库迁移 python manage.py makemigrations python manage.py migrate ''' ''' 注: # 这就是django2.0问题 authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid') TypeError: __init__() missing 1 required positional argument: 'on_delete' 解决办法: authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) 需要加上 on_delete = models.CASCADE django1 默认加上了 on_delete '''
生成表如下:
注意事项:
- 表的名称
myapp_modelName
,是根据 模型中的元数据自动生成的,也可以覆写为别的名称 id
字段是自动添加的- 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
- 这个例子中的
CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。 - 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py
所在应用的名称。 - 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
三、多表 - 添加
from django.shortcuts import render,HttpResponse from app01.models import * def add(request): # 单表 pub = Publish.objects.create(name='人名出版社',city='陕西',email='1234@qq.com') # =============================绑定一对多的关系================================== # 方式一 book -- publish book_obj = Book.objects.create(title='西游记',publishDate='2012-12-1',price=100,publish_id=1) print(book_obj.title) # 西游记 print(book_obj.publish) # Publish object (1) print(book_obj.publish_id) # 1 # 方式二 pub_obj = Publish.objects.filter(nid = 2).first() # 对象 book_obj = Book.objects.create(title='放风筝得人',publishDate='2012-1-2',price=150,publish=pub_obj) print(book_obj.title) # 放风筝得人 print(book_obj.price) # 150 print(book_obj.publish_id) # 3 print(book_obj.publish) # Publish object (3) print(book_obj.publish.name) # 人名出版社 print(book_obj.publish.city) # 陕西 # 查询西游记这本书,出版社对应的邮箱 book_obj = Book.objects.filter(title='西游记').first() print(book_obj.publish.email) # yuan@163.com
# =============================绑定多对多的关系================================== book_obj = Book.objects.create(title='西游记',publishDate='2009-11-20',price=100,publish_id=3) egon = Author.objects.get(name='egon') alex = Author.objects.get(name='alex') # Book_author django 自己加的 你没办法操作 加数据 # django 找到第三张表 添加数据 绑定多对多关系的API book_obj.authors.add(egon,alex) book_obj.authors.add(1,2) book_obj.authors.add(*[1,2]) # # 等效于 传位置参数时 加 * # 解除 多对多的 关系 book_obj = Book.objects.filter(nid=4).first() book_obj.authors.remove(2) book_obj.authors.remove(1,2) book_obj.authors.remove(*[1,2]) # 全解除 book_obj.authors.clear() # 查询出所有作者对象集合 print(book_obj.authors.all()) # #queryset [obj1.obj2] # 与这本书关联的所有作者对象 # 查询主键为4 的书籍的 所有作者的名字 print(book_obj.authors.all().values('name')) # # <QuerySet [{'name': 'alex'}, {'name': 'egon'}]>
http://www.cnblogs.com/yuanchenqi/articles/8963244.html
http://www.cnblogs.com/yuanchenqi/articles/8978167.html
add(obj1[, obj2, ...])
create(**kwargs)
remove(obj1[, obj2, ...])
clear()
set()方法
四、查询 - 基于对象 - 跨表
def add(request): # =============================基于对象的跨表查询=================== ''' 一对多 按字段 :publish (正向查询按字段) book ----》 publish 《--- 按表名 book_set.all() (反向查询按表名) ''' ''' 一对一 按字段 :authordetail (正向查询按字段) author ----》 authordetail 《--- 按表名 author (反向查询按表名) ''' ''' 多对多 按字段 :authors (正向查询按字段) book ----》 author 《--- 按表名 book_set.all() (反向查询按表名) ''' ''' (0.000) select city from publish where nid =( select publish_id from book where nid = 1; ) ---------------基于对象的sql 子查询----------------- SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."nid" = 1 ORDER BY "app01_book"."nid" ASC LIMIT 1; args=(1,) SELECT "app01_publish"."nid", "app01_publish"."name", "app01_publish"."city", "app01_publish"."email" FROM "app01_publish" WHERE "app01_publish"."nid" = 1; args=(1,) ''' # 正向查询 按字段 # 查询主键为1的书籍的出版社所在的城市 book_obj = Book.objects.filter(nid = 1).first() print(book_obj.publish.city) # beijing # 反向查询 按表名 # 查询人名出版社出版的所有书籍的名称 publish_obj = Publish.objects.filter(name='人名出版社').first() print(publish_obj.book_set.all()) # queryset [book1,book2] # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>,...]> # for obj in publish_obj.book_set.all(): # print(obj.title) # 正向查询 # 查询alex的手机号 alex = Author.objects.filter(name='alex').first() print(alex.authordetail.telephone) # 反向查询 # 查询手机号为119 的作者名字 ad = AuthorDetail.objects.filter(telephone=119).first() print(ad.author.name) # 正向查询 # 查询三国演义所有作者的名字 book_obj = Book.objects.filter(title='三国演义').first() print(book_obj.authors.all().values('name')) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]> # <QuerySet [{'name': 'alex'}, {'name': 'egon'}]> # 反向查询 # alex 出版过的所有书籍的名称 alex = Author.objects.filter(name='alex').filter() print(alex.book_set.all()) print(alex.book_set.all().values('title')) # <QuerySet [<Book: 金瓶书>, <Book: 三国演义>]> # <QuerySet [{'title': '金瓶书'}, {'title': '三国演义'}]> # for obj in alex.book_set.all(): # print(obj.title) # 金瓶书 # 三国演义
注意:
你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Article model 中做一下更改:
publish
=
ForeignKey(Book, related_name
=
'bookList'
)
那么接下来就会如我们看到这般:
# 查询 人民出版社出版过的所有书籍
publish
=
Publish.objects.get(name
=
"人民出版社"
)
book_list
=
publish.bookList.
all
()
# 与人民出版社关联的所有书籍对象集合
五、查询 - 基于双下划线(join)- 跨表
Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止。
关键点:正向查询按字段,反向查询按表名。
def add(request): # =============================基于双下划线 (queryset)(sql 是join 查询) 的跨表查询=================== # 不分一对一,一对多 正向查询按字段 反向查询 按表名 # 1. 查询人名出版社出版过的所有书籍的名称和价格(一对多) ret = Publish.objects.filter(name='人名出版社').values('book__title','book__price') print(ret) ''' <QuerySet [{'book__title': '红楼梦1','book__price': Decimal('100.00')}, {'book__title': '红楼梦2', 'book__price': Decimal('100.00')}, {'book__title': '红楼梦3', 'book__price': Decimal('100.00')}, {'book__title': '红楼梦4', 'book__price': Decimal('100.00')}, {'book__title': '红楼梦5', 'book__price': Decimal('100.00')}, {'book__title': '西游记', 'book__price': Decimal('100.00')}]> SELECT "app01_book"."title", "app01_book"."price" FROM "app01_publish" LEFT OUTER JOIN "app01_book" ON ("app01_publish"."nid" = "app01_book"."publish_id") WHERE "app01_publish"."name" = '人名出版社1' LIMIT 21; args=('人名出版社1',) ''' ret = Book.objects.filter(publish__name='人名出版社').values('title','price') print(ret) ''' <QuerySet [{'title': '三国演义', 'price': Decimal('200.00')}, {'title': '三国演义2', 'price': Decimal('200.00')}, {'title': '金瓶mei', 'price': Decimal('200.00')}]> SELECT "app01_book"."title", "app01_book"."price" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_publish"."name" = '人名出版社2' LIMIT 21; args=('人名出版社2',) ''' # 2.查询alex 出版过的所有书籍的名字(多对多) join 的sql 语句 正向按字段 反向按表名 ret = Author.objects.filter(name='alex').values('book__title') # <QuerySet [{'book__title': '金瓶mei'}, {'book__title': '三国演义'}]> ret = Book.objects.filter(authors__name='alex').values('title') # <QuerySet [{'title': '金瓶mei'}, {'title': '三国演义'}]> # 3.混合使用 # 查询人名出版社出版过的所有书籍的名字以及作者的名字 ret = Book.objects.filter(publish__name='人名出版社').values('title','authors__name') # <QuerySet [{'title': '三国演义', 'authors__name': 'alex'},{'title': '金瓶shu', 'authors__name': None}]> ''' (0.000)SELECT "app01_book"."title", "app01_author"."name" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") LEFT OUTER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") LEFT OUTER JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") WHERE "app01_publish"."name" = '人名出版社2' LIMIT 21; args=('人名出版社2',) ''' # 混合使用 手机号以151 开头的作者出版过的所有书籍名称以及出版社名称 ret = Book.objects.filter(authors__authordetail__telephone__startswith = '151').values('title','publish__name') print(ret) # <QuerySet [{'title': '金瓶mei', 'publish__name': '人名出版社2'}, {'title': '三国演义', 'publish__name': '人名出版社2'}]> ''' (0.000) SELECT "app01_book"."title", "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") INNER JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") INNER JOIN "app01_authordetail" ON ("app01_author"."authordetail_id" = "app01_authordetail"."nid") INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_authordetail"."telephone" LIKE '151%' ESCAPE '\' LIMIT 21; args=('151%',) '''
注意:
反向查询时,如果定义了related_name ,则用related_name替换表名,例如:
publish
=
ForeignKey(Blog, related_name
=
'bookList'
)
六、聚合查询 - 分组查询
def add(request): # =============================聚合查询与分组查询============================== # 1.计算所有图书的平均价格 # select avg(price) from book (avg count sum min ) from django.db.models import Avg,Max,Count ret = Book.objects.all().aggregate(c = Avg('price')) # {'price__avg': 160.0} {'c': 160.0} ret = Book.objects.all().aggregate(Max('price')) # {'price__max': Decimal('200.00')} # 分组 统计每一本书 作者的个数 (group by) ret = Book.objects.all().annotate(c = Count('authors__name')) print(ret) # 查询出的结果 看不出 需要 循环 查看count for obj in ret: print(obj.title,obj.c) ''' 红楼梦 0 三国演义 2 三国 0 ''' ''' (0.000) SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price", "app01_book"."publish_id", COUNT("app01_author"."name") AS "c" FROM "app01_book" LEFT OUTER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") LEFT OUTER JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") GROUP BY "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price", "app01_book"."publish_id"; args=() ''' # 统计每一个作者出版过的书籍最高价格 ret = Author.objects.all().annotate(max_price = Max('book__price')) print(ret) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]> for obj in ret: print(obj.name,obj.max_price) # alex 300.00 # egon 200.00 # 每一个出版社 出版过的书籍的平均价格 ret = Publish.objects.all().annotate(avg_price = Avg('book__price')).values('name','avg_price') print(ret) ''' <QuerySet [{'name': '人名出版社1', 'avg_price': 100.0}, {'name': '人名出版社2', 'avg_price': 216.66666666666666}, {'name': '人名出版社3', 'avg_price': 200.0}, {'name': '人名出版社4', 'avg_price': None}, {'name': '人名出版社5', 'avg_price': None}, {'name': '人名出版社6', 'avg_price': None}]> ''' for obj in ret: print(obj.name,obj.avg_price) ''' 人名出版社1 100.0 人名出版社2 216.66666666666666 人名出版社3 200.0 人名出版社4 None '''
聚合
aggregate(*args, **kwargs)
# 计算所有图书的平均价格
>>>
from
django.db.models
import
Avg
>>> Book.objects.
all
().aggregate(Avg(
'price'
))
{
'price__avg'
:
34.35
}
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。
>>> Book.objects.aggregate(average_price
=
Avg(
'price'
))
{
'average_price'
:
34.35
}
如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
>>>
from
django.db.models
import
Avg,
Max
,
Min
>>> Book.objects.aggregate(Avg(
'price'
),
Max
(
'price'
),
Min
(
'price'
))
{
'price__avg'
:
34.35
,
'price__max'
: Decimal(
'81.20'
),
'price__min'
: Decimal(
'12.99'
)}
分组
annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。
统计每一本书的作者个数
bookList
=
Book.objects.annotate(authorsNum
=
Count(
'authors'
))
for
book_obj
in
bookList:
(book_obj.title,book_obj.authorsNum)
统计每一个出版社的最便宜的书
publishList
=
Publish.objects.annotate(MinPrice
=
Min
(
"book__price"
))
for
publish_obj
in
publishList:
(publish_obj.name,publish_obj.MinPrice)
annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:queryResult= Publish.objects .annotate(MinPrice=Min("book__price")) .values_list("name","MinPrice") print(queryResult)
统计每一本以py开头的书籍的作者个数:queryResult=Book.objects .filter(title__startswith="Py") .annotate(num_authors=Count('authors'))
统计不止一个作者的图书:queryResult=Book.objects .annotate(num_authors=Count('authors')) .filter(num_authors__gt=1)
根据一本图书作者数量的多少对查询集 QuerySet进行排序:Book.objects.annotate(num_authors
=
Count(
'authors'
)).order_by(
'num_authors'
)
查询各个作者出的书的总价格:# 按author表的所有字段 group by queryResult=Author.objects
.annotate(SumPrice=Sum("book__price"))
.values_list("name","SumPrice") print(queryResult) # 按authors__name group by queryResult2=Book.objects.values("authors__name")
.annotate(SumPrice=Sum("price"))
.values_list("authors__name","SumPrice") print(queryResult2)
七、F查询 - Q查询
。。。
http://www.cnblogs.com/yuanchenqi/articles/8963244.html
F查询
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
示例1:
查询评论数大于收藏数的书籍
from django.db.models import F models.Book.objects.filter(commnet_num__gt=F('keep_num'))
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
models.Book.objects.filter(commnet_num__lt=F('keep_num')*2)
修改操作也可以使用F函数,比如将每一本书的价格提高30元
models.Book.objects.all().update(price=F("price")+30)
引申:
如果要修改char字段咋办?
如:把所有书名后面加上(第一版)
>>> from django.db.models.functions import Concat >>> from django.db.models import Value >>> models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))
Q查询
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
示例1:
查询作者名是小仙女或小魔女的
models.Book.objects.filter(Q(authors__name="小仙女")|Q(authors__name="小魔女"))
你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。
示例:查询作者名字是小仙女并且不是2018年出版的书的书名。
>>> models.Book.objects.filter(Q(author__name="小仙女") & ~Q(publish_date__year=2018)).values_list("title") <QuerySet [('番茄物语',)]>
查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。
例如:查询出版年份是2017或2018,书名中带物语的所有书。
>>> models.Book.objects.filter(Q(publish_date__year=2018) | Q(publish_date__year=2017), title__icontains="物语") <QuerySet [<Book: 番茄物语>, <Book: 香蕉物语>, <Book: 橘子物语>]>
八、关联管理器
。。。 http://www.cnblogs.com/yuanchenqi/articles/8978167.html
===================================================================
http://www.cnblogs.com/liwenzhou/p/8660826.html
http://www.cnblogs.com /yuanchenqi/articles/8978167.html
https://docs.djangoproject.com/en/1.11/ref/models/querysets/
九、补充知识
1. 内容回顾 1. 常用字段和字段参数 1. 常用字段 1. AutoField primary_key=True # 设置为主键 2. CharField max_length=32 # 设置最大长度 3. IntegerField 4. BigInterField 5. TextField 6. DateField auto_now_add # 创建这条数据时自动添加当前时间 auto_now # 每次更新的时候都自动更新时间 7. DateTimeField 同上 ... 常用参数: default="" # 设置默认值 null=True # 可以为空 unique=True # 该字段在数据库中不能重复 2. 关系字段 1. 外键 ForeignKey 1. 外键通常放在多(一对多的多)的那一边 2. 参数 1. to=“表名” 2. related_name="xx" 用来替换反向查询时的 表名_set 3. on_delete=models.CASCADE 2. 一对一 OneToOneField 1. 什么时候用 作者和作者详情 3. 多对多 ManyToManyField 1. 三种方式 1. 不用ManyToMany 2. 自带的ManyToMany, 自动帮我创建第三张表 3. 自定义第三张表 # 相亲网站 # 男孩 class Boy(models.Model): name = models.CharField(max_length=32) girls = models.ManyToManyField(to='Girl', through="Info", through_fields=("boy1", "girl1")) # 能满足多对多的关系,但是少点东西 # 女孩 class Girl(models.Model): name = models.CharField(max_length=32) # through_fields=('field1', 'field2'), # 你把多对多建在那个表,field1就是这个表的名字 # field2是你目标表的表名 # boys = models.ManyToManyField(to=Boy, through="Info", through_fields=("girl1", "boy1")) # 能满足多对多的关系,但是少点东西 # 约会记录 # 男孩1 女孩1 # 男孩2 女孩1 # 男孩1 女孩2 # 自己创建第三张表, 记录约会的记录 class Info(models.Model): girl1 = models.ForeignKey(to=Girl) boy1 = models.ForeignKey(to=Boy) # 其他补充字段 date = models.DateTimeField(auto_now_add=True) 3. 元信息 # 定义元信息 class Meta: ordering = ("price", ) # 默认按照价格排序 db_table = "book" # 指定在数据库中创建表的表名 unique_together = ("title", "price") # 多字段联合唯一 2. ORM操作 1. 单表13个 --> 永远不要怀疑自己!要自信!!! 混乱即阶梯! 返回QuerySet的有: 1. all() 3. filter() 4. exclude() 7. values_list() --> 元祖 8. values() --> 字典 9. order_by() 10. reverse() 13. distinct() 返回对象: 2. get() 5. first() 6. last() 返回数字: 11. count() 返回布尔值: 12. exist() 双下划线: id__lt=10 ... 跨表的双下划线: models.Book.objects.filter(author__name=“小仙女") models.Book.objects.filter(author__detail__age=18) ... 2. 关系表的操作 1. 外键 1. 正向查找 --> 具体的对象 直接找 2. 反向查找 --> 对象的列表 .表名(小写)_set.all() 2. 多对多 1. 正向查找 直接找 --> 对象的列表 2. 反向查找 表名_set.all() --> 对象的列表 多对多才有的: .create() --> author_obj.books.create(title="番茄物语") .add(1,2,3) .clear() -->清空 .remove(1) .set([1,2,3]/QuerySet对象) 3.聚合和分组 1. aggregate() 2. annotate() ---> GROUP BY 4. F和Q 1. 同一张表的不同列作比较 2. 多个条件做查询 5. 事务 try: from django.db import transaction with transaction.atomic(): new_publisher = models.Publisher.objects.create(name="新华出版社CCC") # 再去创建新书 # new_book = models.Book.objects.create(title="新华字典", price=3.5, publisher_id=new_publisher.id) new_book = models.Book.objects.create(titl="新华字典CCC", price=3.5, publisher=new_publisher) except Exception as e: print(str(e)) 6. 如何在Python脚本加载Django环境 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "项目名.settings") import django django.setup() # 引用Django内部的变量
事务
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings") import django django.setup() import datetime from app01 import models try: from django.db import transaction with transaction.atomic(): new_publisher = models.Publisher.objects.create(name="火星出版社") models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10) # 指定一个不存在的出版社id except Exception as e: print(str(e))
Django终端打印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', }, } }
在Python脚本中调用Django环境
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings") import django django.setup() from app01 import models books = models.Book.objects.all() print(books)
orm参数
https://www.cnblogs.com/liwenzhou/p/8688919.html