55.ORM外鍵:引用同app下的不一樣模型,引用不一樣app下的模型,引用模型自身使用詳解

外鍵和表關係

外鍵是屬於數據庫級別的,在MySQL中,表有兩種引擎,一種是InnoDB,另一種是myisam。若是使用的是InnoDB引擎,是支持外鍵約束的。外鍵的存在使得ORM框架在處理表關係的時候異常強大。所以這裏咱們首先來介紹外鍵在Django中的使用。

類定義爲 class ForeignKey(to,on_delete,**options)。第一個參數to是應用的哪一個模型(也就是應用的表),第二個參數on_delete在使用外鍵應用的模型數據被刪除了,這個字段該如何處理。舉例說明,若是有一個user和一個Article兩個模型。一個user能夠發表多篇文章,一個Article只能有一個Author,而且經過外鍵進行應用。

1. 使用外鍵引用同一個APP中的不一樣模型,示例代碼以下:

# 注意:在定義一個模型的時候,模型的名字的首字母必定要大寫,否者的話,模型名字下面會出現波浪線。
class User(models.Model):
    username = models.CharField(max_length=20)
    password = models.CharField(max_length=100)

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

    author = models.ForeignKey('User',on_delete=models.CASCADE)
使用ForeignKey來定義模型之間的關係,即在article的實例中能夠經過author屬性來作對應的User模型。這樣使用起來很是方便。

views.py文件中實現向數據庫表中添加一條數據,示例代碼以下:

from django.http import HttpResponse
from  .models import User,Article


def index(request):
    # 向數據庫表中添加一條數據,首先要先將被引用的表添加數據,並進行保存
    user = User(username='孤煙逐雲', password='hello')
    user.save()
    article = Article(title='Python', content='真好')
    article.author = user
    article.save()
    return HttpResponse("Success ! ")
爲何使用了ForeignKey後,就能經過author屬性訪問到對應的user對象呢?

由於在底層,Django爲Article表添加了一個屬性名_id的字段(好比author的字段名稱是author_id),這個字段是一個外鍵,記錄着對應的做者的主鍵。之後經過article.author訪問的時候,其實是經過author_id找到對應的數據,而後再提取user表中的這條數據,造成一個模型。python

展現表User中的數據:

在這裏插入圖片描述

展現表article中的數據:

在這裏插入圖片描述

views.py文件實現從數據庫表中查詢數據,而且打印輸出,示例代碼以下:

from django.http import HttpResponse
from  .models import User,Article


def index(request):
    article = Article.objects.all()
    print(article)
    return HttpResponse("Success ! ")
此時的打印結果爲:

在這裏插入圖片描述

重寫Article類的__str__(self)方法,將數據顯示出來,示例代碼以下:
class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey('User',on_delete=models.CASCADE)

    def __str__(self):
        return "<(Article id: %s, title: %s, content: %s, author: %s)>" % (self.id, self.title, self.content, self.author)
再次運行項目進行打印輸出,數據具體信息:

在這裏插入圖片描述

2. 使用外鍵引用另一個app的模型

那麼應該在傳遞to參數的時候,使用app.model_name進行指定。以上例爲例,若是User和Article不是在同一個APP中,那麼在引用的時候的示例代碼以下:
# Book模型在book,app中,
from django.db import models


class Book(models.Model):
# 定義屬性,出版社的地址
    pub_add = models.CharField(max_length=100)


# 在article模型中進行外鍵引用
class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    # 使用外鍵引用同一個app下的模型
    author = models.ForeignKey('User',on_delete=models.CASCADE)
    # 使用外鍵引用不一樣app下的模型
    pub = models.ForeignKey('book.Book',on_delete=models.CASCADE)
在使用命令python manage.py migrate將遷移腳本文件映射到數據庫中的過程當中,出現django.db.utils.IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (orm_relationship _demo.#sql-158c_79, CONSTRAINT article_article_pub_id_e2e65cb7_fk_book_book_id FOREIGN KEY (pub_id) REFERENCES book _book (id))')
解決辦法就是將settings.py文件中的DATABASE配置"default"變量中,添加:
# 取消對外鍵的檢查
 'OPTIONS':{
        "init_command":"SET foreign_key_checks = 0;",
    }
以後再次使用命令python manage.py migrate 就沒有任何錯誤出現了。
來到navicat中查看映射生成的表:
book表中的字段信息

在這裏插入圖片描述

article表中的字段信息:

在這裏插入圖片描述

查看article_artilce表中外鍵的引用狀況,由輸出信息能夠看出,引用了同一個app:article中的user表和不一樣app:book中的book表。

在這裏插入圖片描述

3.使用外鍵引用自己模型

'to'參數能夠爲'self',或者是這個模型的名字,在論壇開發中,通常的評論均可以進行二級評論,便可以針對另一個評論進行評論,那麼在定義模型的時候就須要使用外鍵來引用資深了,示例代碼以下:
class Comment(models.Model):
    content = models.TextField()
    origion_comment = models.ForeignKey('self',on_delete=models.CASCADE)
查看article_comment這個表:

在這裏插入圖片描述

相關文章
相關標籤/搜索