前言
假如有一張表(Card)記錄用戶的卡號信息和用戶名,現在需要新增一個小功能,記錄用戶的手機號,郵箱和住址等更多信息。
為了不影響原來的表設計,可以新增一張表(CardDetail),專門記錄用戶的其它更多信息。
銀行賬戶(Card)和聯系方式(CardDetail),一個銀行賬戶對應一個聯系人,而一個聯系人也只對應一個賬戶,這就是一對一關系。
一對一表設計
在models.py創建數據模型, Card表記錄卡號、姓名、添加時間基本的信息,CardDetail使用OneToOneField關聯Card表,記錄電話、郵箱、城市、詳細地址。
OneToOneField里面有兩個參數必填,第一個參數傳關聯的表名稱,第二個參數on_delete=models.CASCADE(對象刪除后,包含OneToOneField的字段也會被刪除)
# models.py
from django.db import models
# Create your models here.
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="添加時間")
class Meta:
verbose_name_plural = '銀行卡賬戶'
verbose_name = "銀行卡賬戶_基本信息"
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_plural = '個人資料'
verbose_name = "賬戶_個人資料"
def __str__(self):
return self.card.card_user
admin.py設置后台頁面顯示詳情
# admin.py
from django.contrib import admin
from hello import models
# Register your models here.
class MoreInfo(admin.StackedInline):
model = models.CardDetail
@admin.register(models.Card)
class ControlCard(admin.ModelAdmin):
list_display = ["card_id", "card_user", "add_time"]
# 在Card頁面顯示更多信息CardDetail
inlines = [MoreInfo]
表設計好之后執行下面兩句
makemigrations會在當前目錄下生成一個migrations文件夾,該文件夾的內容就是數據庫要執行的內容
python manage.py makemigrations
migrate就是執行之前生成的migrations文件,這一步才是操作數據庫的一步
python manage.py migrate
inlines關聯顯示
為了讓 CardDetail 里面信息和Card的信息在一個頁面上展示,這里需用到 inlines 參數,關聯過去。
先寫一個MoreInfo類,繼承了admin.StackedInline,StackedInline是讓關聯的字段縱向顯示,多說無益,直接看效果。
列表頁面

編輯頁面

StackedInline和TabularInline
StackedInline是縱向顯示,顯示效果如上面圖,TabularInline是橫線顯示,顯示效果如下圖
# amdin.py
# StackedInline改成StackedInline
class MoreInfo(admin.StackedInline):
model = models.CardDetail
@admin.register(models.Card)
class ControlCard(admin.ModelAdmin):
list_display = ["card_id", "card_user", "add_time"]
# 在Card頁面顯示更多信息CardDetail
inlines = [MoreInfo]

