ディレクトリ
DjangoのORMマルチテーブルのCRUD
関係フィールドを作成します。
ORMは、フィールドを使用して、マルチテーブルのリレーションシップを作成します。一般的に使用されるマルチテーブルの関係は以下のとおりです。
- ForeignKeyの外部キー、フィールド、多くの関係
- OneToOneField 1つの関係フィールド
- ManyToManyField-多くの関係フィールド
で直接見てmodels.py
コード:
class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField()
# 一对一
ad=models.OneToOneField(to="AuthorDetail", to_field="id", on_delete=models.CASCADE)
# to_field="id" 可以不写,默认找主键
# to="AuthorDetail", to=可以不用写
# on_delete=models.CASCADE 默认是级联删除,想做级联更新,直接去数据库修改表结构
# on_delete=models.SET_NULL 也可以设置成删除置空
class AuthorDetail(models.Model):
birthday=models.DateField()
telephone=models.CharField(max_length=16)
addr=models.CharField(max_length=64)
class Publish(models.Model):
name=models.CharField(max_length=32)
city=models.CharField(max_length=32)
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", to_field="id", on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
table文の基本的な構成は、単一テーブルの操作と一致しています。多くのテーブルがあります関係1、多くの、多くの1つ、1多くに、それぞれ、以下の3通りの方法で作成することができました:
# 一对一,外键 + 唯一
ad=models.OneToOneField(to="AuthorDetail", to_field="id", on_delete=models.CASCADE)
# 一对多,外键
publishs=models.ForeignKey(to="Publish", to_field="id", on_delete=models.CASCADE)
# 多对多,创建第三张表
authors=models.ManyToManyField(to='Author')
多くの対応テーブルを1または1を操作するとき、私たちはクラスの属性テーブルやフォームフィールドを操作することができ、フィールド名が通常です类属性名 + 下划线 + 外键名
。
- クラス
ad
のプロパティ:、publishs
- フィールド:
ad_id
、publishs_id
第三世代の新しいテーブル、テーブル名の多く-直接操作するために应用名 + 下划线 + 当前表名 + 下划线 + 属性名
、第三のクラスの属性テーブルのフィールドとテーブルで動作させることができます。
- クラスのプロパティ:
authors
- テーブル名:
app01_book_authors
id
フィールド:author_id
、、book_id
それは彼らの特定の使用状況以下に詳細に説明します。
マルチテーブルCRUD
追加
マンツーマン
上述したように、一つのフィールドは、別のテーブルまたはクラス属性テーブルのフィールドの使用を介して関連するデータを増加させるために添加してもよいです。
models.AuthorDetail.objects.create(
birthday='2018-11-11',
telephone='15122220000',
addr='北京',
)
models.Author.objects.create(
name='金龙',
age=2,
ad=models.AuthorDetail.objects.get(id=1), # 类属性
)
models.Author.objects.create(
name='金龙2',
age=2,
ad_id=2, # 表字段
)
多くの
あなたが追加したり、クラスの属性テーブルのフィールドを介してすることができ、同じ理由で、一対多で、増やします。
models.Book.objects.create(
title='白洁',
publishDate='2011-01-01',
price=200,
publishs=models.Publish.objects.get(id=1) # 类属性
)
models.Book.objects.create(
title='白洁第二部',
publishDate='2011-01-01',
price=300,
publishs_id=1 # 表字段
)
多くの多くの
この本は、著者が多くの本を書くことができ、複数の著者を持つことができます。例えば、本の第1号は、2人の著者によって書かれ、著者と書籍のテーブル間の関係、その後、1と2の番号を付け、我々は、それを2冊1 2 1著者と書籍の著者1の関係を作成する必要がありますこのように:
+----+---------+-----------+
| id | book_id | author_id |
+----+---------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
+----+---------+-----------+
2つの方法で特定の動作は、一方がオブジェクトを介して追加され、他方は直接添加した値であります
オブジェクトによって、オブジェクトを追加します。
オブジェクトのオブジェクトを見つけることによって、追加するには、Addメソッドを使用します。
book_obj = models.Book.objects.get(id=1)
author1 = models.Author.objects.get(id=1)
author2 = models.Author.objects.get(id=2)
book_obj.authors.add(author1, author2)
# book_obj.authors.add(*[author1, author2])
主キーIDを付加することにより、
著者IDで、著者情報を直接本を追加します:
book_obj = models.Book.objects.get(id=1)
book_obj.authors.add(1, 2)
# book_obj.authors.add(*[1, 2])
[削除]
一対一や一対多
一から一とオブジェクトを見つけることが、多くの1つ後のオブジェクトを削除され、直接削除します:
models.Author.objects.get(id=1).delete()
多くの多くの
多対削除操作は、クエリオブジェクトを使用する必要があります:
book_obj = models.Book.objects.get(id=1) # 找到id为1的书
book_obj.authors.remove(3) #删除id为1的书与id为3的作者之间的关系
book_obj.authors.remove(2, 3) # 删除id为1的书与id为2和3的作者之间的关系
book_obj.authors.clear() # 清空id为1的书的所有作者信息
修正
一対一や一対多
更新を変更し、1対多とシングルテーブルが同じです。
models.Book.objects.filter(id=1).update(
title='白洁新版',
# publishs=models.Publish.objects.get(id=3),
publishs_id=3
)
多くの多くの
book_obj.authors.set(['4',]) # 先清空再添加 clear+add
お問い合わせ
クロステーブルのクエリオブジェクトに基づいて、
マンツーマン
フォワード問い合わせ
2ゴールデンドラゴンは、著者のホームアドレスを問い合わせます
author_obj = models.Author.objects.get(name='金龙2')
# author_obj.ad -- 直接拿到authordetail表中的那个条记录对象
print(author_obj.ad.addr)
逆引き参照
著者名の先頭に151のお問い合わせ番号
authordetail_obj = models.AuthorDetail.objects.filter(telephone__startswith='151').first()
print(authordetail_obj.author.name)
多くの
フォワード問い合わせ
で公開されている書籍のバイ・ジー新バージョン
book_obj = models.Book.objects.filter(title='白洁新版').first()
print(book_obj.publishs.name)
逆引き参照
東京の出版社が本を出版しました
pub_obj = models.Publish.objects.get(name='东京出版社')
books = pub_obj.book_set.all().values('title')
# 东京出版社出版的名称中还有白洁的那些书
books = pub_obj.book_set.filter(title__contains='白洁').values('title')
print(books)
多くの多くの
フォワード問い合わせ
持っているこの本の著者のバイ・ジー新バージョン
book_obj = models.Book.objects.filter(title='白洁新版').first()
authors = book_obj.authors.all().values('name')
print(authors)
逆引き参照
何本についてのお問い合わせは、金龍2を書き込みます
jinlong2_obj = models.Author.objects.get(name='金龙2')
ret = jinlong2_obj.book_set.all().values('title')
print(ret)
クロステーブルのクエリの概要
- プロパティにより、フォワード・クエリ
- あなたが1であれば、小文字でクラス名で検索逆
- そして、多対多、小文字_setでクラス名で検索逆
クロステーブルダブル下線のクエリに基づいて(参加します)
マンツーマン
財産上のフォワード・リンクされたテーブル
クエリ旭東のホームアドレス
ret = models.Author.objects.filter(name='旭东').values('ad__addr')
print(ret)
SQL文で表現した場合、それは次のようになります。
select app01_authordetail.addr from app01_author inner join app01_authordetail on app01_author.ad_id = app01_authordetail.id where app01_author.name='旭东';
でも小文字でテーブルのクラス名を逆に
ret = models.AuthorDetail.objects.filter(author__name='旭东').values('addr')
print(ret)
多くの
東京で出版され何冊発見。
場合はSQL文の直接の使用は記述する必要があります。
select app01_book.title from app01_publish inner join app01_book on app01_publish.id = app01_book.publishs_id where app01_publish.name='东京出版社';
ORMの使用は、次のように書かれています:
ret = models.Publish.objects.filter(name='东京出版社').values('book__title')
print(ret)
ret = models.Book.objects.filter(publishs__name='东京出版社').values('title')
print(ret)
多くの多くの
何本についてのお問い合わせは、金龍2を書き込みます
ret = models.Book.objects.filter(authors__name='金龙2').values('title')
print(ret)
ret = models.Author.objects.filter(name='金龙2').values('book__title')
print(ret)
集計クエリ
集計集計クエリ、結果は通常の辞書、クエリセットのターミネータです。
from django.db.models import Avg,Max,Min,Count,Sum
obj = models.Book.objects.all().aggregate(a=Max('price')) #{'price__avg': 200.0}
print(obj)
Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
クエリをグループ化
SQL文で書かれたクエリをグループ化すると、次のようになります。
group by app01_book.publishs_id
たとえば:によって公開された各書籍の最高価格を見つけます
最初のグループの値の後に
ret = models.Book.objects.values('publishs_id').annotate(m=Max('price'))
print(ret)
概要:グループ化するための基礎としてのカッコ内のフィールド値に基づいて、意味のフロント注釈に書かれた値は、。注釈あなたがしなければならない統計結果があります。したがって、結果は辞書であるクエリセットタイプのデータを、返されます。
{'publishs_id':1,'m':100}
最初のグループの値の後に
ret = models.Publish.objects.annotate(m=Max('book__price')).values('m', 'name')
print(ret)
要約:注釈を直接意味、オブジェクトの背面に書かれたその前の表に従ったデータのすべてのグループの(デフォルトのid値です)。戻り結果は、すべてのモデルが値によって値次いで(各オブジェクトは、その統計モデルオブジェクトを含む)テーブルの前にオブジェクト、ということです。場合辞書別名、またクエリセットタイプの値フィールドは、統計結果を書き込むと指示することができます。
{'m': 100, 'name': '东京出版社'}
各著者の名前と本の出版のための最高価格を照会します。
ret = models.Book.objects.values('authors__name', 'authors__id').annotate(m=Max('price')) # group by authors__name,authors__id
print(ret)
ret = models.Author.objects.annotate(m=Max('book__price')).values('name', 'm')
print(ret)
クエリF
インポートの方法:
from django.db.models import F
結果は、2つのフィールドを比較した後、資格表Fクエリ結果セットです。
ポイントのようにすべての書籍のコメントの数についての問い合わせの数よりも大きいです。
過去には、我々はまた、ループを使用して見つけることができます:
list1 = []
books = models.Book.objects.all()
for i in books:
if i.dianzan > i.comment:
list1.append(i)
あなたはFクエリを使用している場合、コードはよりシンプルかつ直感的になります。
ret = models.Book.objects.filter(dianzan__gt=F('comment')).values('title')
ret = models.Book.objects.filter(dianzan__lt=F('comment')).values('title')
print(ret)
フィールドこの4つの事業:
models.Book.objects.all().update(
price=F('price') + 20 # 支持四则运算
)
Qクエリ
インポートの方法:
from django.db.models import Q
実行するクエリQの論理演算、コネクタのQ:
& -- and
| -- or
~ -- not,取反
300未満ポイントの大きなに関するお問い合わせなどの書籍300の価格より
ret = models.Book.objects.filter(Q(dianzan__gt=300)|~Q(price__lt=500),xx='oo').values('title')
ret = models.Book.objects.filter(Q(dianzan__gt=300)).values('title')
ret = models.Book.objects.filter(Q(Q(dianzan__gt=300)|~Q(price__lt=500))&Q(xx='oo')).values('title') # Q查询能够进行各种复杂条件的拼接
print(ret)
マルチテーブルは、練習の例を照会します。
# 1 查询每个作者的姓名以及出版的书的最高价格
ret = models.Author.objects.values('id','name').annotate(m=Max('book__price'))
print(ret)
# 2 查询作者id大于2作者的姓名以及出版的书的最高价格
ret = models.Author.objects.filter(id__gt=2).values('name').annotate(a=Max('book__price'))
print(ret)
# 3 查询作者id大于2或者作者年龄大于等于3岁的女作者的姓名以及出版的书的最高价格
ret = models.Author.objects.filter(Q(id__gt=2)|Q(Q(age__gte=3)&Q(sex='女'))).values('name').annotate(a=Max('book__price'))
print(ret)
# 4 查询每个作者出版的书的最高价格 的平均值
ret = models.Book.objects.values('authors__name').annotate(m=Max('price')).aggregate(a=Avg('m'))
print(ret)
# 5 每个作者出版的所有书的最高价格以及最高价格的那本书的名称
ret = models.Book.objects.values('authors__name').annotate(m=Max('price'))
queryset({'authors__name':'xx','m':100},{'authors__name':'xx','m':100},)