<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Django模型關(guān)系:從一對多到多對多全解析

      一、一對多關(guān)系: ForeignKey

      一對多是最常見的模型關(guān)系,例如 "作者 - 書籍" 場景:假設(shè)一個作者可以寫多本書,但每本書只能屬于一個作者。

      定義關(guān)系

      核心參數(shù)說明:

      • on_delete=models.CASCADE:當(dāng)作者被刪除時,關(guān)聯(lián)的書籍也會被自動刪除
      • related_name='books':定義反向查詢名稱,可通過author.books.all()獲取作者的所有書籍
      from django.db import models
      
      class Author(models.Model):
          first_name = models.CharField(max_length=100)
          last_name = models.CharField(max_length=100)
      
          def __str__(self):
              return f"{self.first_name} {self.last_name}"
      
      class Book(models.Model):
          title = models.CharField(max_length=100)
          publication_date = models.DateField()
          # 外鍵關(guān)聯(lián)Author,級聯(lián)刪除,反向查詢名為books
          author = models.ForeignKey(
              Author, 
              on_delete=models.CASCADE, 
              related_name='books'
          )
      
          def __str__(self):
              return self.title
      

      數(shù)據(jù)操作示例

      創(chuàng)建數(shù)據(jù)

      # 創(chuàng)建作者
      author1 = Author.objects.create(first_name='J.K.', last_name='Rowling')
      author2 = Author.objects.create(first_name='George', last_name='Orwell')
      
      # 創(chuàng)建書籍并關(guān)聯(lián)作者
      book1 = Book.objects.create(
          title='Harry Potter', 
          publication_date='1997-06-26', 
          author=author1
      )
      book2 = Book.objects.create(
          title='1984', 
          publication_date='1949-06-08', 
          author=author2
      )
      

      查詢操作

      # 正向查詢:通過書籍找作者
      book = Book.objects.get(title='1984')
      print(book.author)  # 輸出: George Orwell
      
      # 反向查詢:通過作者找書籍
      author = Author.objects.get(last_name='Rowling')
      for book in author.books.all():
          print(book.title)  # 輸出: Harry Potter
      

      高級配置

      禁用外鍵約束:當(dāng)需要靈活管理關(guān)聯(lián)關(guān)系(如允許刪除存在關(guān)聯(lián)數(shù)據(jù)的主表記錄)時,可關(guān)閉數(shù)據(jù)庫級約束

      author = models.ForeignKey(
          Author, 
          on_delete=models.SET_NULL,
          related_name='books',
          db_constraint=False,  # 不創(chuàng)建數(shù)據(jù)庫外鍵約束
          null=True
      )
      

      自定義數(shù)據(jù)庫列名:默認(rèn)會生成<ClassName>_id列,可通過db_column修改

      dept_id = models.ForeignKey(
          "SystemDept",
          on_delete=models.SET_NULL,
          db_column="dept_id",  # 顯式指定數(shù)據(jù)庫列名
          null=True
      )
      

      二、多對多關(guān)系: ManyToManyField

      多對多關(guān)系適用于 "作者 - 書籍" 的另一種場景:假設(shè)一個作者可以寫多本書,一本書也可以有多個作者。

      定義關(guān)系

      Django 會自動創(chuàng)建中間表(默認(rèn)名為appname_book_authors)存儲關(guān)聯(lián)關(guān)系,無需手動定義。

      from django.db import models
      
      class Author(models.Model):
          name = models.CharField(max_length=100)
          email = models.EmailField()
      
          def __str__(self):
              return self.name
      
      class Book(models.Model):
          title = models.CharField(max_length=200)
          publication_date = models.DateField()
          # 多對多關(guān)聯(lián)Author
          authors = models.ManyToManyField(Author, related_name='books')
      
          def __str__(self):
              return self.title
      

      數(shù)據(jù)操作示例

      添加 / 移除關(guān)聯(lián)

      # 創(chuàng)建實例
      author1 = Author.objects.create(name='Alice', email='alice@example.com')
      author2 = Author.objects.create(name='Bob', email='bob@example.com')
      book = Book.objects.create(title='Example Book', publication_date='2023-01-01')
      
      # 添加關(guān)聯(lián)
      book.authors.add(author1, author2)
      
      # 移除關(guān)聯(lián)
      book.authors.remove(author1)
      

      查詢操作

      # 正向查詢:書籍的所有作者
      book = Book.objects.get(title='Example Book')
      for author in book.authors.all():
          print(author.name)
      
      # 反向查詢:作者的所有書籍
      author = Author.objects.get(name='Bob')
      for book in author.books.all():  # related_name='books'
          print(book.title)
      

      自定義中間表

      當(dāng)需要存儲關(guān)聯(lián)關(guān)系的額外信息(如邀請原因、加入時間)時,可自定義中間表

      class Membership(models.Model):
          group = models.ForeignKey(Group, on_delete=models.CASCADE)
          person = models.ForeignKey(Person, on_delete=models.CASCADE)
          inviter = models.ForeignKey(Person, related_name="invites", on_delete=models.CASCADE)
          invite_reason = models.CharField(max_length=64)  # 額外信息
      
      class Group(models.Model):
          name = models.CharField(max_length=128)
          members = models.ManyToManyField(
              Person,
              through="Membership",  # 指定中間表
              through_fields=("group", "person"),  # 關(guān)聯(lián)字段
          )
      

      三、性能優(yōu)化技巧

      select_related:用于一對多關(guān)系,提前加載關(guān)聯(lián)對象,減少數(shù)據(jù)庫查詢

      # 普通查詢(N+1問題)
      entries = Entry.objects.all()
      for entry in entries:
          print(entry.blog.name)  # 每次循環(huán)都會觸發(fā)新查詢
      
      # 優(yōu)化后(僅1次查詢)
      entries = Entry.objects.select_related('blog').all()
      for entry in entries:
          print(entry.blog.name)  # 使用緩存數(shù)據(jù)
      

      批量操作:利用update()進行批量更新,避免循環(huán)操作

      # 批量標(biāo)記站內(nèi)信為已讀
      SystemNotifyMessage.objects.filter(
          id__in=ids.split(",")
      ).update(
          read_status=True, 
          read_time=timezone.now()
      )
      

      四、關(guān)于是否使用外鍵約束

      在實際項目中,是否使用數(shù)據(jù)庫外鍵約束需要權(quán)衡利弊

      使用外鍵的優(yōu)勢

      • 數(shù)據(jù)完整性:數(shù)據(jù)庫級別的約束保證關(guān)聯(lián)數(shù)據(jù)一致性
      • 開發(fā)效率:ORM 自動處理關(guān)聯(lián)查詢和級聯(lián)操作
      • 查詢便捷:支持select_related等優(yōu)化方法,簡化多表查詢

      禁用外鍵的場景

      • 高并發(fā)系統(tǒng):外鍵會增加數(shù)據(jù)庫鎖競爭,影響寫入性能
      • 分布式架構(gòu):分庫分表環(huán)境下,跨庫外鍵無法生效
      • 復(fù)雜遷移:避免循環(huán)依賴導(dǎo)致的遷移失敗問題

      折中方案:使用db_constraint=False 參數(shù)

      • 數(shù)據(jù)庫層面:無外鍵約束,數(shù)據(jù)庫不會強制校驗關(guān)聯(lián)數(shù)據(jù)的存在性
      • Django ORM 層面:保留邏輯關(guān)聯(lián),ORM仍將字段視為外鍵關(guān)系(邏輯關(guān)聯(lián)),支持 ORM 查詢、操作語法
      特性 db_constraint=True (默認(rèn)) db_constraint=False
      數(shù)據(jù)庫外鍵約束 創(chuàng)建,強制數(shù)據(jù)一致性 不創(chuàng)建
      級聯(lián)操作 數(shù)據(jù)庫自動處理 僅由 Django ORM 處理
      關(guān)聯(lián)數(shù)據(jù)存在性校驗 數(shù)據(jù)庫強制校驗 不校驗(需應(yīng)用層保障)
      ORM 查詢支持 完整支持 完整支持(邏輯外鍵保留)
      性能影響 外鍵約束帶來額外開銷 無約束開銷
      適用場景 強數(shù)據(jù)一致性需求 高頻寫入/跨庫/歷史數(shù)據(jù)遷移

      五、多對多關(guān)系實戰(zhàn)

      實戰(zhàn)場景:在一個后臺管理系統(tǒng)中,用戶與角色往往是多對多關(guān)系。一個用戶可以分配多個角色,一個角色也可以屬于多個用戶。

      image-20250730171424143

      模型定義:點擊查看完整代碼

      class SystemUsers(BaseModel, AbstractBaseUser):
          id = models.BigAutoField(primary_key=True, db_comment="用戶ID", help_text="用戶ID")
          username = models.CharField(
              max_length=30, unique=True, db_comment="用戶賬號", help_text="用戶賬號"
          )
          # ...
          # 與角色多對多關(guān)系
          roles = models.ManyToManyField(
              "SystemRole",
              through="SystemUserRole",
              through_fields=("user_id", "role_id"),
              related_name="users",
          )
          # ...    
          
      class SystemUserRole(BaseModel):
          """用戶和角色關(guān)聯(lián)中間表"""
          id = models.BigAutoField(primary_key=True, db_comment="id")
          user_id = models.ForeignKey(
              "SystemUsers",
              on_delete=models.CASCADE,
              db_constraint=False,
              db_column="user_id",
              db_comment="用戶ID",
          )
          role_id = models.ForeignKey(
              "SystemRole",
              on_delete=models.CASCADE,
              db_constraint=False,
              db_column="role_id",
              db_comment="角色ID",
          )
      
          class Meta:
              managed = True
              db_table = "system_user_role"
              db_table_comment = "用戶和角色關(guān)聯(lián)表"
              ordering = ["-id"]
      

      system_user_role數(shù)據(jù)庫生成的中間表

      image-20250730172028007


      您正在閱讀的是《Django從入門到實戰(zhàn)》專欄!關(guān)注不迷路~

      posted @ 2025-07-30 17:45  小王子1024  閱讀(222)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 北辰区| 久久亚洲欧美日本精品| 九九热在线这里只有精品| 国产色无码专区在线观看| 国产精品麻豆欧美日韩ww| 亚洲国产欧美不卡在线观看| 丰满人妻熟妇乱又仑精品| 亚洲成av人片在www鸭子| 日本黄页网站免费大全| 国产超碰无码最新上传| 日韩精品一区二区亚洲av| 亚洲精品自拍在线视频| 亚洲阿v天堂网2021| 2021国产精品视频网站| 国产成人黄色自拍小视频| 国产特级毛片aaaaaa高清| 亚洲精品一区久久久久一品av | 精品国产一区二区三区av性色| 午夜免费啪视频| 无码日韩做暖暖大全免费不卡| 亚洲欧美v国产蜜芽tv| 狠狠色噜噜狠狠狠狠2021| 亚洲熟女乱色一区二区三区| 国产亚洲精品第一综合另类无码无遮挡又大又爽又黄的视频 | 激情综合网五月婷婷| 又黄又无遮挡AAAAA毛片| 国产精品麻豆中文字幕| 无码人妻精品一区二区三区下载| 日本黄页网站免费观看| 久久夜色精品亚洲国产av| 99热精品国产三级在线观看| 鲁一鲁一鲁一鲁一澡| 狠狠亚洲色一日本高清色| 丹阳市| 大地资源高清免费观看| 亚洲人成在久久综合网站| 国产一级av在线播放| 亚洲情色av一区二区| 爆乳女仆高潮在线观看| 美女人妻激情乱人伦| 国产免费高清69式视频在线观看 |