Database_ManyToMany


M:N関係


ManyToManyField'sの概念と特性

  • マルチペアマルチリレーションシップを確立するためのモデルフィールド
  • 必要な位置パラメータ(M:N関係に設定するモデルクラス)
  • モデル」フィールドの「RelatedManager」を使用して、関連オブジェクトを追加、削除または作成できます.
  • add(), remove(), create(), clear...
  • RelatedManager
  • マルチペアマルチまたはマルチペアマルチ関連コンテキストで使用するマネージャ
  • .

    ManyToManyField's Arguments


    related_name

  • ターゲットモデル(リレーショナルフィールドを持たないモデル)ソースモデル(リレーショナルフィールドを含むモデル)を参照する場合(逆参照)に使用するマネージャ名
  • を設定します.
  • ForeignKeyの関連名と同じ
  • through

  • ブローカ・テーブルを直接作成する場合は、throughオプションを使用してブローカ・テーブルを表すDjangoモデル
  • を指定できます.
  • は、一般に、仲介テーブルで追加データを使用する多対多関係を接続するために使用される.

    symmetrical

  • ManyToManyFieldは、同じモデルを指す定義でのみ
  • を使用します.
  • 対称=True(デフォルト)の場合、Djangoはpersonsetマネージャ
  • を追加しません.
  • ソースモデルのインスタンスがターゲットモデルのインスタンスを参照する場合、ターゲットモデルのインスタンスもソースモデルのインスタンスを自動的に参照します.
  • つまり、もし私があなたの友达だったら、あなたも私の友达
  • です.
    対称
  • が望ましくない場合はFalse
  • Follo機能による
  • の実現

    Related Manager

  • 1:NまたはM:Nコンテキストで使用する管理者
  • 同名の方法の使用および挙動は、各関係(1:N、M:N)に依存する.
  • 1:Nターゲットモデルインスタンス
  • のみを提供する
  • M:N関係に係る2つのオブジェクトは、いずれも
  • を用いることができる.

    add


    指定オブジェクト
  • を関連オブジェクトセット
  • に追加する.
  • 既存の関係については、
  • はコピーされません.
  • モデルの例では、パラメータ
  • としてフィールド値(PK)を許可する
    追加
  • doc idとpatient idを同じ病名に更新したい場合は?
  • は既に関係があるので、addマネージャとしてはしばらく使用できません.
  • 更新したいなら、それなりの保留を持ってきて、更新すればいいです.
  • reservation = Reservation.objects.get(pk=1)
    
    reservation.symptom = 'x'
    reservation.save()
  • 同じ患者が同じ医者の異なる病気で来たら?
  • 直接予約していちいち追加…?
  • reservation = Reservation()
    reservation.symptom='a'
    reservation.patient_id=1
    reservation.doctor_id=1
    reservation.save()

    remove

  • 関連オブジェクトセットから指定モデルオブジェクト
  • を削除する.
  • 内部Query Set.delete()を使用して関係を削除する
  • モデルの例では、パラメータ
  • としてフィールド値(PK)を許可する

    透過例

  • モデル関係
  • を設定する
    class Doctor(models.Model):
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 의사 {self.name}'
    
    
    class Patient(models.Model):
        doctors = models.ManyToManyField(Doctor, through='Reservation')
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 환자 {self.name}'
    
    
    class Reservation(models.Model):
        doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
        patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
        #증상
        symptom = models.TextField()
        #예약일자
        reserved_at = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return f'{self.doctor.pk}번 의사의 {self.patient.pk}번 환자'
  • 医師1名と患者2名
  • を生成
    doctor1 = Doctor.objects.create(name='justin')
    patient1 = Patient.objects.create(name='tony')
    patient2 = Patient.objects.create(name='harry')
  • 計画
  • の作成
    #예약 만들기(증상을 담아서)
    reservation1 = Reservation(doctor=doctor1, patient=patient1, symptom='headache')
    #예약 저장
    reservation1.save()
    #의사의 예약 
    doctor1.patient_set.all()
    patient1.doctors.all()
    
    #환자의 입장에서 예약 만들기
    patient2.doctors.add(doctor1, through_defaults={'symptom': 'flu'})
    doctor1.patient_set.all()
    patient2.doctors.all()

  • チェックシート


  • 計画の削除
  • doctor1.patient_set.remove(patient1)
    patient2.doctors.remove(doctor1)

    データベース内の表現

  • Djangoマルチペアマルチリレーションシップを表す仲介テーブル
  • を作成する.
  • テーブル名は、複数のフィールドの名前と、これらのフィールドを含むモデルのテーブル名とを組み合わせた
  • である.

    ブローカ・テーブル・フィールドを作成するルール

  • ソースモデルとターゲットモデルが異なる
  • id
  • _id
  • _id
  • ManyToManyFieldは同じモデルを指します(再帰的には自分を指します)
  • id
  • from <model>_id
  • to_<model>_id