Database M:N関係Intro


M:N関係


INTRO:病院カルテシステムを用いて多対多関係を知る

  • 患者と医師が使用する病院のカルテシステムを確立する
  • 病院システムの中で最も核心的な対象は何ですか?->患者と医師
  • 両者の関係をどのように表現しますか?
  • 開始前
  • モデリングは、現実世界を最大限に反映することを目的としています.
  • は、私たちの日常生活に近い例によってデータベースをモデリングし、内部データの流れをどのように制御するかを考慮します.
  • 練習モード

    #models.py
    class Doctor(models.Model):
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 의사 {self.name}'
    
    
    class Patient(models.Model):
        doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 환자 {self.name}'
    doctor1 = Doctor.objects.create(name='justin')
    doctor2 = Doctor.objects.create(name='eric')
    patient1 = Patient.objects.create(name='tony', doctor=doctor1)
    patient2 = Patient.objects.create(name='harry', doctor=doctor2)
    hospital_doctor
    idname1justin2eric
    hospitals_patient
    idnamedoctor_id1tony12harry23tony2
    patient3 = Patient.objects.create(name='tony', doctor=doctor2)

    1:N制限


    1番患者(トニー)が1番医師の診療を終え、2番医師に会いに行きたい場合は、新たな予約が必要です.
  • 新規保存期間の作成
  • 新しく生成された3号患者は1号患者とは異なる
  • を予約したい人は同じですが、問題はインスタンスが異なることです.
  • patient4 = Patient.objects.create(name='harry', doctor=doctor1, doctor2)
  • 一度に2人の医者に診てもらいたい
  • 外部キーに2つのダミーデータを含めることはできません
  • 新しい計画を作成できません
  • 新しいオブジェクトを作成する必要がある
  • 複数の医師のカルテを1人の患者に保存することはできません
  • 外部キーは「1,2」形式のデータ
  • を使用できません.

    仲介モード

  • 関連テーブル
  • を作成
    iddoctor_idpatient_id...

  • 移行中のファイルとdbを消去して既存の移行を初期化

  • 新しいモデルの適用
  • from django.db import models
    
    
    class Doctor(models.Model):
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 의사 {self.name}'
    
    
    # 외래키 삭제
    class Patient(models.Model):
        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)
    
        def __str__(self):
            return f'{self.doctor_id}번 의사의 {self.patient_id}번 환자'
  • 計画
  • の作成
    In [1]: doctor1 = Doctor.objects.create(name='justin')
    
    In [2]: patient1 = Patient.objects.create(name='tony')
    
    In [3]: Reservation.objects.create(doctor=doctor1, patient=patient1)
    Out[3]: <Reservation: 1번 의사의 1번 환자>
  • 医師と患者は診療を照会する際に逆参照を用いる.
  • #의사의 예약환자 조회
    In [4]: doctor1.reservation_set.all()
    Out[4]: <QuerySet [<Reservation: 1번 의사의 1번 환자>]>
    #환자의 진료의사 조회
    In [5]: patient1.reservation_set.all()
    Out[5]: <QuerySet [<Reservation: 1번 의사의 1번 환자>]>
  • 患者1名と医師1名を追加して予約
  • を作成
    In [7]: Reservation.objects.create(doctor=doctor1, patient=patient2)
    Out[7]: <Reservation: 1번 의사의 2번 환자>
  • 医師の予約患者
  • を調べる
    In [9]: doctor1.reservation_set.all()
    Out[9]: <QuerySet [<Reservation: 1번 의사의 1번 환자>, <Reservation: 1번 의사의 2번 
    환자>]>
    1人の医者は複数の患者を診療することができ、1人の患者は複数の医者を診療することができ、1つの関係を形成した.

    ManyToManyField


  • ManyToManyField ?

  • 多対多の関係を作成するためのモデルフィールド

  • 必要な位置パラメータ(M:N関係に設定するモデルクラス)が必要です.

  • ManyToManyFiledの作成(ブローカモデルの削除)
  • フィールドに入力位置は、DoctorまたはPatterの
  • であってもよい.
  • DB削除後初期化遷移

  • ManyToManyFiledの適用
  • class Doctor(models.Model):
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 의사 {self.name}'
    
    class Patient(models.Model):
        # ManyToManyField 작성
        doctors = models.ManyToManyField(Doctor)
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 환자 {self.name}'

  • 作成したテーブルはブローカモデルと同じです
  • 1:Nでは、外部キーは無条件に依存関係にあるが、M:Nはピア関係であるため、MTMフィールドをクラスの1つに配置することができる.
  • のみが、ManyToManyFiledの場所に基づいて参照と逆参照の関係を変更します.
  • 以上の場合は、DoctorがPatterを参照し、PatterがDoctorの関係を参照する.

  • 医者1人と患者2人
  • doctor1 = Doctor.objects.create(name='justin')
    patient1 = Patient.objects.create(name='tony')
    patient2 = Patient.objects.create(name='harry')
  • 予約の生成(患者参照)
  • #환자1이 의사1에게 예약 진행 
    patient1.doctors.add(doctor1)
    #patient1이 예약한 의사 목록 확인
    patient1.doctors.all()
    Out[6]: <QuerySet [<Doctor: 1번 의사 justin>]>
    #doctor1에게 예약된 환자 목록 확인 
    doctor1.patient_set.all()
    Out[7]: <QuerySet [<Patient: 1번 환자 tony>]>
  • 計画の生成(「逆参照」を参照)
  • #의사 1에게 환자2 추가 
    doctor1.patient_set.add(patient2)
    #의사가 맡은 환자들조회 
    doctor1.patient_set.all()
    Out[9]: <QuerySet [<Patient: 1번 환자 tony>, <Patient: 2번 환자 harry>]>
    patient2.doctors.all()
    Out[10]: <QuerySet [<Doctor: 1번 의사 justin>]>
    patient1.doctors.all()
    Out[11]: <QuerySet [<Doctor: 1번 의사 justin>]>
  • 予約キャンセル
  • #1번 환자 삭제 
    doctor1.patient_set.remove(patient1)
    #2번 환자만 남음 
    doctor1.patient_set.all()
    Out[13]: <QuerySet [<Patient: 2번 환자 harry>]>
    #1번 환자의 예약정보는 사라짐 
    patient1.doctors.all()
    Out[14]: <QuerySet []>
  • 予約キャンセル2
  • #2번 환자의 예약 중 1번 의사 삭제 
    patient2.doctors.remove(doctor1)
    #2번 환자의 예약정보 사라짐 
    patient2.doctors.all()
    Out[19]: <QuerySet []>
    #1번 의사의 예약 정보 사라짐 
    doctor1.patient_set.all()
    Out[20]: <QuerySet []>

    related_name

  • 1:Nはrelated nameを使用せずtargetmodel setを使用し、M:Nはrelated nameを使用して両者を区別する!
  • 新しいモデル
    from django.db import models
    
    
    class Doctor(models.Model):
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 의사 {self.name}'
    
    
    class Patient(models.Model):
        # ManyToManyField - related_name 작성
        doctors = models.ManyToManyField(Doctor, related_name='patients')
        name = models.TextField()
    
        def __str__(self):
            return f'{self.pk}번 환자 {self.name}'
  • の新しいモデルを作成すると、逆参照を考慮することなく、両方のモデルを同じ形式で参照できます.
  • #환자 1의 모든 예약 조회 
    patient1.doctors.all()
    #의사 1의 모든 예약 조회
    doctor1.patients.all()

    Djangoでの仲介モデル

  • Django ManyToManyFieldによってブローカテーブル
  • が自動的に作成される
  • の場合、仲介テーブルを直接作成する場合はありますか?
  • ブローカ・テーブルを手動で指定する場合は、throughオプションを使用してブローカ・テーブルを表すDjangoモデル
  • を指定できます.
  • の最も一般的な用途は、追加のデータを使用して仲介テーブルと多対多の関係を確立する場合は、
  • を使用します.

    サマリ

  • 実際のDoctorとPatterテーブルは変わりません.
  • 1:N関係は完全従属関係であるが、M:N関係は医者を見る患者と患者を見る医者の2つの形式として表現することができる.