zoukankan      html  css  js  c++  java
  • 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']

    浏览器访问结果

  • 相关阅读:
    为什么分库分表使用2的N次方 一个字节用两位16进制
    2018总结:理财(韭菜)、工作、生活
    为什么跨语言开发不是件难事
    nginx 关于client_max_body_size client_body_buffer_size配置
    mac openresty 源码安装 坑
    PIC32MZ tutorial -- Change Notification
    PIC32MZ tutorial -- Key Debounce
    PIC32MZ tutorial -- Timer Interrupt
    PIC32MZ tutorial -- Blinky LED
    PIC32MZ tutorial -- Hello World
  • 原文地址:https://www.cnblogs.com/chushujin/p/12533851.html
Copyright © 2011-2022 走看看