ORM リンク テーブル操作
django で orm を学習する場合、1 対多と多対多を前方探索と後方探索の 2 つの方法に分けることができます。
前方参照: ForeignKey は UserInfo テーブルにあります。UserInfo テーブルから他のテーブルのクエリを開始する場合、これは順方向の操作であり、UserType テーブルから他のテーブルのクエリを開始する場合、これは逆の操作です。
- 一対多: モデル。外部キー (他のテーブル)
- 多対多: モデル。ManyToManyField (その他のフォーム)
- 一対一:モデル。1 対 1 フィールド (他のテーブル)
フォワード リンク テーブル操作の概要:
いわゆる順結合テーブル操作と逆結合テーブル操作の ID は、Foreign_Key フィールドが配置されているテーブルによってのみ決定されます。
Foreign_Key フィールドは、任意のテーブルのテーブルを結合するために使用できます。それ以外の場合は、Foreign_Key フィールドに関連付けられた小文字のテーブル名が使用されます。
-
一対多: オブジェクト。外部キー。関連テーブル フィールド、値 (外部キー フィールド_関連テーブル フィールド)
-
多対多: 外部キー フィールド。全て()
逆結合テーブル操作の概要:
-
値、値のリスト、およびフィルターでテーブル間をリバース: 小文字の tablename_associated テーブル フィールド
-
オブジェクトごとにテーブルを逆にします: 小文字の surface _set.all()。
-
all(): すべて取得
-
フィルター: もう一度フィルターをかけます
Class.objects.filter(id=1).first().stu_set.filter(name__startswith='o')
-
フィールド関係:
-
フィールド リレーションシップは、django がテーブル リレーションシップを維持する方法です。主に 1 対 1、多対 1、多対多があります。
-
現在の 1 対 1 および多対 1 の関係では、次のように、関連付けられたデータが削除されたときの操作を記述するためにon_delete属性を設定する必要があります。
- models.CASCADE: 関連付けられたデータを削除し、関連付けられたデータを削除します
- models.PROTECT: 関連するデータを削除し、エラー ProtectedError を発生させます
- models.SET_NULL: それに関連付けられた値が null に設定されています (前提として、FK フィールドを null 許容に設定する必要があります)。
- models.SET_DEFAULT: 関連するデータを削除し、関連する値をデフォルト値に設定します (FK フィールドをデフォルト値に設定する必要があります)。
- models.DO_NOTHING: 関連データを削除し、何もしません
1 対 1 の関係:
たとえば、教師テーブルがあり、教授テーブルが必要な場合、教授テーブルには教師テーブルの一連の属性が含まれている可能性があり、教師テーブルのフィールドを教授に直接コピーしたくない教授テーブル継承教師テーブルを実装するには、 OneToOneFieldを使用できます。
模型类使用OneToOneField用来定义一对一关系;
OneToOneField(to,on_delete,parent_link=False,options)
class Child(models.Model):
name=models.CharField(max_length=100,verbose_name='姓名')
age=models.CharField(max_length=100,verbose_name='年纪')
def __str__(self):
return self.name
class Man(models.Model):
child=models.OneToOneField(to=Child,verbose_name='小孩',on_delete=models.CASCADE)
Responsibility=models.BooleanField(verbose_name='责任',default=True)
def __str__(self):
return self.child.name
python .\manage.py shell
from myapp.models import *
c1=Child.objects.create(name='张三',age='18') #添加一条数据到child表
m1=Man.objects.create(child=c1)
m1.child --><Child: 张三>
m1.child.name -->'张三'
c1.delete() --> {'myapp.Man': 1, 'myapp.Child': 1}) 删除被继承的表的数据 继承的表数据也同时被删除
多対一の関係
Django は django.db.models.ForeignKey を使用して多対 1 の関係を定義しますForeignKey
には位置パラメータが必要です: モデルに関連付けられたクラス
人生における多対 1 の関係: クラスの教師、クラスの関係。校長は多くのクラスを率いることができますが、各クラスには校長が 1 人しかいません
class Headmaster(models.Model):
name=models.CharField(max_length=50)
def __str__(self):
return self.name
class Class(models.Model):
class_name=models.CharField(max_length=50)
teacher=models.ForeignKey(Headmaster,null=True,on_delete=models.SET_NULL)
def __str__(self):
return self.class_name
>>> H1 = Headmaster(name='渔夫')
>>> H1.save()
>>> H1
<Headmaster: 渔夫>
>>> H2 = Headmaster(name='农夫')
>>> H2.save()
>>> Headmaster.objects.all()
[<Headmaster: 渔夫>, <Headmaster: 农夫>]
以上创建了两条老师数据
由于我们设置外键关联可以为空 null=True ,所以此时在班级表创建时,可以直接保存,不需要提供老师数据
>>> C1 = Class(class_name='一班')
>>> C2 = Class(class_name='二班')
#如果外键设置不为空时,保存会引发以下错误
# IntegrityError: NOT NULL constraint failed: bbs_class.teacher_id
>>> C1.teacher = H1
>>> C2.teacher = H2
>>> C1.save()
>>> C2.save()
将老师分配个班级之后,由于班级表关联了老师字段,我们可以通过班级找到对应老师
虽然老师表中没有关联班级字段,但是也可以通过老师找到他所带的班级,这种查询方式也叫作关联查询
通过模型类名称后追加一个'_set',来实现反向查询
>>> H1.class_set.all()
<QuerySet [<Class: 一班>]>
由于我们这是一个多对一的关系,也就说明我们的老师可以对应多个班级
我们可以继续给H1老师分配新的班级
>>> C3 = Class(class_name='三班')
>>> C3.teacher = H1
>>> C3.save()
>>> H1.class_set.all()
[<Class: 一班>, <Class: 三班>]
- クラスは 1 人の教師にしか対応できず、外部キーは一意であるため、引き続き新しい教師をクラス C1 に割り当てると、以前の教師の情報は上書きされ、新しい教師は保存されません。
多対多の関係
多対多の関係は、 ManyToManyFieldフィールドを使用してモデルで定義されます
多対多の関係は、関連付けることも関連付けないこともできるため、 on_delete 属性を明示的に指定する必要はありません. 人生では、
多対多の関係: ミュージシャンは複数のバンドに所属でき、バンドは複数のバンドを持つことができますミュージシャン
class Artist(models.Model):
artist_name=models.CharField(max_length=50)
def __str__(self):
return self.artist_name
class Band(models.Model):
band_name=models.CharField(max_length=50)
artist=models.ManyToManyField(Artist)
def __str__(self):
return self.band_name
创建音乐家以及乐队
>>> from bbs.models import Artist,Band
>>> A1 = Artist.objects.create(artist_name='Jack')
>>> A2 = Artist.objects.create(artist_name='Bob')
>>> B1 = Band.objects.create(band_name='FiveMonthDay')
>>> B2 = Band.objects.create(band_name='SHE')
创建出两个乐队之后对其进行音乐家的添加
多对多字段添加时,可以使用 add 函数进行多值增加
>>> B1.artist.add(A1,A2)
>>> B2.artist.add(A2)
B1 乐队含有 A1 , A2 两名成员
B2 乐队含有 A1 成员
>>> B1.artist.all()
[<Artist: Bob>, <Artist: Jack>]
>>> B2.artist.all()
[<Artist: Jack>]
可以在音乐家表中查找某个乐家属于哪些乐队
>>> Band.objects.filter(artist=A1) # 这里使用的是我们模型类来进行查找。
[<Band: SHE>, <Band: FiveMonthDay>] # A1乐家属于,SHE以及FiveMonthDay
>>> Band.objects.filter(artist=A2)
[<Band: SHE>]
也可以查找这音乐家在哪个乐队
>>> A1.band_set.all() # 直接通过具体数据对象进行查找
[<Band: SHE>, <Band: FiveMonthDay>]
>>> A2.band_set.all()
[<Band: SHE>]
多对多关联字段的删除,要使用 remove 来进行关系的断开
而不是直接使用 delete , remove 只会断开数据之间的联系,但是不会将数据删除
现在在B1乐队中删除A1乐家
>>> B1.artist.remove(A1)
>>> B1.artist.all()
<QuerySet [<Artist: Bob>]>