首页 技术 正文
技术 2022年11月11日
0 收藏 994 点赞 4,616 浏览 19306 个字

一、多表 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 2alex 出版过的书籍名称 (子查询:以一个查询的结果作为下一个查询的条件)
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 和 两个关联字段
一旦确定是 一对一
怎么建立一对一的关系?---》 在两张表中的任意一张表中建立关联字段 + uniquePublish
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.nameclass 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 '''

生成表如下:

Django – 模型层 – 下

Django – 模型层 – 下

Django – 模型层 – 下

Django – 模型层 – 下

Django – 模型层 – 下

注意事项:

  • 表的名称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,HttpResponsefrom 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) # # 方式二
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) #
print(book_obj.publish_id) #
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()方法

Django – 模型层 – 下

Django – 模型层 – 下

Django – 模型层 – 下

Django – 模型层 – 下

Django – 模型层 – 下

四、查询 – 基于对象 – 跨表

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 = '').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, MaxMin

  >>> 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:    print(book_obj.title,book_obj.authorsNum)

统计每一个出版社的最便宜的书

  publishList=Publish.objects.annotate(MinPrice=Min("book__price"))

  for publish_obj in publishList:    print(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 osif __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 osif __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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,031
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,859