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']

浏览器访问结果

原文地址:https://www.cnblogs.com/chushujin/p/12533851.html