前面在admin後臺頁面經過設置外鍵,能夠選擇下拉框的選項,本篇主要講解關於外鍵(ForeignKey)的查詢python
在上一篇的基礎上新增一個BankName表,Card表經過外鍵關聯到BankNameweb
class BankName(models.Model): '''銀行信息''' bank_name = models.CharField(max_length=50, verbose_name="銀行名稱", default="") city = models.CharField(max_length=30, verbose_name="城市", default="") point = models.CharField(max_length=60, verbose_name="網點", default="") class Meta: verbose_name = '銀行' verbose_name_plural = verbose_name def __str__(self): return self.bank_name class Card(models.Model): '''銀行卡 基本信息''' card_id = models.CharField(max_length=30, verbose_name="卡號", default="") card_user = models.CharField(max_length=10, verbose_name="姓名", default="") add_time = models.DateField(auto_now=True, verbose_name="添加時間") bank_info = models.ForeignKey(BankName, on_delete=models.CASCADE, default="") class Meta: verbose_name = "銀行卡帳戶_基本信息" verbose_name_plural = '銀行卡帳戶' def __str__(self): return self.card_id class CardDetail(models.Model): '''銀行卡詳情信息''' card = models.OneToOneField(Card, on_delete=models.CASCADE, verbose_name="卡號" ) tel = models.CharField(max_length=30, verbose_name="電話", default="") mail = models.CharField(max_length=30, verbose_name="郵箱", default="") city = models.CharField(max_length=10, verbose_name="城市", default="") address = models.CharField(max_length=30, verbose_name="詳細地址", default="") class Meta: verbose_name = "帳戶_我的資料" verbose_name_plural = verbose_name def __str__(self): return self.card.card_user
以後執行 makemigrations 和migrate,同步數據shell
python manage.py makemigrations
python manage.py migratedjango
爲了調試方便,能夠使用django的shell模式,對錶的數據增刪改查操做,打開cmd,cd到manage.py目錄函數
python manage.py shell測試
先新增數據測試數據設計
D:\web_djo\helloworld>python manage.py shell >>> from hello.models import Card, BankName >>> a = BankName.objects.create(bank_name='上海銀行', city='上海', point='徐家彙區') >>> a.save >>> c = Card.objects.create(card_id='62270121022100000', card_user='張三', bank_info=a) >>> c.save
根據Card表的card_id,去查詢關聯的對應的BankName相關信息,這個相對來講簡單一點調試
>>> from hello.models import BankName, Card >>> cardxx=Card.objects.get(card_id='62270121022100000') >>> cardxx.card_user '張三' >>> cardxx.bank_info <BankName: 上海銀行> >>> cardxx.bank_info.bank_name '上海銀行' >>> cardxx.bank_info.city '上海' >>>
若是想經過銀行名稱「上海銀行」,查詢到此銀行關聯多少張卡,而且查詢其中一個銀行卡的信息。
反向查詢,當ForeignKey沒設置related_name參數,默認是經過關聯表的名稱加_set去查詢code
>>> bank = BankName.objects.get(bank_name='上海銀行') >>> bank.city '上海' # 反向查詢,表名稱_set >>> bank.card_set.all() <QuerySet [<Card: 62270121022100000>]> # count()函數統計 >>> bank.card_set.all().count() 1 >>> bank.card_set.all()[0].card_id '62270121022100000' >>>
當Card表的外鍵(ForeignKey)只有一個時,能夠經過_set去查詢到,當有多個外鍵時,就沒法查詢具體哪一個外鍵了,這時候就須要加個related_name參數。對象
class CardGrade(models.Model): '''會員等級''' nub = models.CharField(max_length=50, verbose_name="會員等級", default="") class Meta: verbose_name = '會員等級' verbose_name_plural = verbose_name class BankName(models.Model): '''銀行信息''' bank_name = models.CharField(max_length=50, verbose_name="銀行名稱", default="") city = models.CharField(max_length=30, verbose_name="城市", default="") point = models.CharField(max_length=60, verbose_name="網點", default="") class Meta: verbose_name = '銀行' verbose_name_plural = verbose_name def __str__(self): return self.bank_name class Card(models.Model): '''銀行卡 基本信息''' card_id = models.CharField(max_length=30, verbose_name="卡號", default="") card_user = models.CharField(max_length=10, verbose_name="姓名", default="") add_time = models.DateField(auto_now=True, verbose_name="添加時間") bank_info = models.ForeignKey(BankName, related_name='card_bank', on_delete=models.CASCADE, default="") grade = models.ForeignKey(CardGrade, related_name='card_grade', on_delete=models.CASCADE, default="") class Meta: verbose_name = "銀行卡帳戶_基本信息" verbose_name_plural = '銀行卡帳戶' def __str__(self): return self.card_id
related_name參數至關於給這個外鍵取了個別名,方便多個外鍵時候去識別。如下是新增數據和正向查詢
**當定義了related_name後」_set」這類查詢就被related_name代替了,因此用」_set」會報錯。**
# 新增數據 >>> from hello.models import CardGrade,BankName,Card >>> n=CardGrade.objects.create(nub='黃金會員') >>> b=BankName.objects.create(bank_name='北京銀行',city='北京') >>> c=Card.objects.create(card_id='666555000111',card_user='楊過', bank_info=b, grade=n) # 正向查詢 >>> c.grade.nub '黃金會員' >>> c.bank_info.city '北京' >>>
反向查詢須要用到related_name參數,以下
# CardGrade表查Card表 >>> nnn=CardGrade.objects.get(nub='黃金會員') >>> nnn.card_grade.all() <QuerySet [<Card: 666555000111>]> >>> nnn.card_grade.all()[0].card_id '666555000111' # BankName表查Card表 >>> bbb=BankName.objects.get(bank_name='上海銀行') >>> bbb.card_bank.all() <QuerySet [<Card: 62270121022100000>]> >>> bbb.card_bank.all()[0].card_id '62270121022100000' >>>