Django测试开发-14-数据库表设计:多对多,一对一,一对多
一、多对多表设计,使用ManyToManyField字段进行关联。
书和作者关系:一本书可以由多个作者,一个作者可以出版多本书,故为多对多模式
1.1 models.py代码:
class Author(models.Model): """作者""" name = models.CharField(max_length=20,verbose_name="作者") mail = models.CharField(max_length=20,verbose_name="邮箱") address = models.CharField(max_length=50,verbose_name="籍贯") mobile = models.CharField(max_length=11,verbose_name="手机号") class Meta: verbose_name_plural = "作者" def __str__(self): return self.name class Book(models.Model): ''' 书籍信息 ''' book_name = models.CharField(max_length=100,verbose_name="书名") # 多对多 auth = models.ManyToManyField(Author,verbose_name="作者") class Meta: verbose_name_plural = "书籍" def __str__(self): return self.book_name
1.2 执行python manage.py makemigrations vote和python manage.py migrate
1.3 admin.py注册
class ControlAuthor(admin.ModelAdmin): list_display = ['name','mail','address','mobile'] class ControlBook(admin.ModelAdmin): list_display = ['book_name','book_auth']
# 定义一个方法,遍历book的auth,然后用列表返回 def book_auth(self,obj): return [a.name for a in obj.auth.all()] admin.site.register(models.Author,ControlAuthor) admin.site.register(models.Book,ControlBook)
1.4 浏览器访问结果:
添加完成书籍后,数据库会生成多对多的关系表
二、一对一表设计,使用OneToOneField指定
2.1 models.py新增表
# 一对一表设计 class Card(models.Model): '''银行卡基本信息''' card_id = models.CharField(max_length=30,verbose_name="卡号",default="") card_user = models.CharField(max_length=20,verbose_name="姓名",default="") create_time = models.DateField(auto_now=True,verbose_name="添加时间") class Meta: verbose_name_plural = "银行卡账户" verbose_name = "银行卡账户_基本信息" def __str__(self): return self.card_id class CardDetails(models.Model): '''银行卡基本信息''' # 一对一 card_num = models.OneToOneField(Card,on_delete=models.CASCADE,verbose_name="卡号") phone = models.CharField(max_length=20,verbose_name="电话",default="") e_mail = models.CharField(max_length=50,verbose_name="邮箱",default="") city = models.CharField(max_length=30,verbose_name="城市",default="") address = models.CharField(max_length=100,verbose_name="详细地址",default="") class Meta: verbose_name_plural = "个人信息" verbose_name = "账户_个人信息" def __str__(self): return self.card_num.card_user
2.2 执行python manage.py makemigrations vote和python manage.py migrate
2.3 admin.py注册
class MoreInfo(admin.StackedInline): model = models.CardDetails class ControlCard(admin.ModelAdmin): list_display = ['card_id','card_user','create_time'] # 在Card页面显示额外信息CardDetail inlines = [MoreInfo] admin.site.register(models.Card,ControlCard)
注意此处跟之前的不一样,MoreInfo继承自admin.StackedInline
ControlCard中指定inlines=[MoreInfo]
浏览器结果如图:
此处注意:如果class MoreInfo(admin.TabularInline):继承TabularInline则下方信息横向展示:
# admin.StackedInline 纵向显示
# admin.TabularInline 横向显示
三、一对多表设计,指定外键
比如银行卡和银行就是一对多的关系,一个银行可以发行多张银行卡,而一张银行卡只能属于一个银行
models.py
# 一对多表设计 class Bank(models.Model): bank_name = models.CharField(max_length=50,verbose_name="银行名称") city = models.CharField(max_length=30,verbose_name="城市") net_point = models.CharField(max_length=100,verbose_name="网点") class Meta: verbose_name_plural = '银行卡' def __str__(self): return self.bank_name class CardInfo(models.Model): ''' 卡信息 ''' card_no = models.CharField(max_length=30,verbose_name="卡号") card_name = models.CharField(max_length=10,verbose_name="姓名") # 增加外键 """ 外键使用方法: 第一个参数(to)是关联到对应的表(Bank),第二个参数的on_delete指的是通过ForeignKey连接起来的对象被删除后,当前字段怎么变化 常见的选项有: models.CASCADE,对象删除后,包含ForeignKey的字段也会被删除 models.PROTECT,删除时会引起ProtectedError models.SET_NULL,注意只有当当前字段设置null设置为True才有效,此情况会将ForeignKey字段设置为null models.SET_DEFAULT ,同样,当前字段设置了default才有效,此情况会将ForeignKey 字段设置为default 值 moels.SET,此时需要指定set的值 models.DO_NOTHING ,什么也不做 """ select_bank = models.ForeignKey(Bank,on_delete=models.CASCADE,verbose_name="选择银行") class Meta: verbose_name_plural = '卡号信息' def __str__(self): return self.card_no
models.ForeignKey()介绍:
#外键使用方法: # 第一个参数(to)是关联到对应的表(Bank),第二个参数的on_delete指的是通过ForeignKey连接起来的对象被删除后,当前字段怎么变化 #常见的选项有: #models.CASCADE,对象删除后,包含ForeignKey的字段也会被删除 #models.PROTECT,删除时会引起ProtectedError #models.SET_NULL,注意只有当当前字段设置null设置为True才有效,此情况会将ForeignKey字段设置为null #models.SET_DEFAULT ,同样,当前字段设置了default才有效,此情况会将ForeignKey 字段设置为default 值 #moels.SET,此时需要指定set的值 #models.DO_NOTHING ,什么也不做
3.2 执行python manage.py makemigrations vote和python manage.py migrate
3.3 admin.py注册
class ControlBank(admin.ModelAdmin): list_display = ['bank_name','city','net_point'] class ControlCardInfo(admin.ModelAdmin): list_display = ['card_no','card_name','select_bank']
浏览器访问结果
当有些人一出生就有的东西,我们要为之奋斗几十年才拥有。但有一样东西,你一辈子都不会有,那就是我们曾经一无所有。