Django框架学习12--一对多,多对多,一对一表的设计

一.一对多表的设计

1.设计表信息,指定外键

比如一张银行卡只能属于一个银行,一个银行可以发行多张银行卡,要表示银行表和银行卡表的关系,可以使用外键来进行关联,在银行卡的model定义中,定义外键,指定所属的银行。

class Bank(models.Model):
    '''银行信息'''
    bank_name = models.CharField(max_length=50, verbose_name="银行名称")
    city = models.CharField(max_length=30, verbose_name="城市")
    point = models.CharField(max_length=60, verbose_name="网点")

    class Meta:
        verbose_name_plural = '银行卡'

    def __str__(self):
        return self.bank_name


class CardInfo(models.Model):
    '''卡信息'''
    card_id = models.CharField(max_length=30, verbose_name="卡号")
    card_name = models.CharField(max_length=10, verbose_name="姓名")
    # 增加外键
    info = models.ForeignKey(Bank, on_delete=models.CASCADE, verbose_name="选择银行")

    class Meta:
        verbose_name_plural = '卡号信息'

    def __str__(self):
        return self.card_id

外键使用方法:

第一个参数(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 ,什么也不做

2.执行python manage.py makemigrations 和python manage.py migrate

3.admin.py注册

class ControlBank(admin.ModelAdmin):
    # 显示的字段
    list_display = ["bank_name", "city", "point"]


class ControlCardInfo(admin.ModelAdmin):
    # 显示的字段
    list_display = ["card_id", "card_name", "info"]


admin.site.register(models.Bank, ControlBank)
admin.site.register(models.CardInfo, ControlCardInfo)

cardinfo表里面有个info_id字段会自动关联到bank表里面的id

二.多对多表设计

多对多表的设计,使用ManyToManyField字段进行关联。

1.设计表信息,指定ManyToManyField

class Auther(models.Model):
    '''作者'''
    name = models.CharField(max_length=10, verbose_name="作者")
    mail = models.CharField(max_length=30, verbose_name="邮箱")
    city = models.CharField(max_length=10, verbose_name="城市")

    class Meta:
        verbose_name_plural = '作者'

    def __str__(self):
        return self.name


class Book(models.Model):
    '''书籍详情'''
    book_name = models.CharField(max_length=50, verbose_name="书名")
    #多对多使用ManyToManyField字段
    auth = models.ManyToManyField(Auther, verbose_name="作者")

    class Meta:
        verbose_name_plural = '书籍详情'

    def __str__(self):
        return self.book_name

2.执行python manage.py makemigrations 和python manage.py migrate

3.admin.py进行注册

class ControlAuther(admin.ModelAdmin):
    # 显示的字段
    list_display = ["name", "city", "mail"]


class ControlBook(admin.ModelAdmin):
    # 显示的字段
    list_display = ["book_name", "作者"]

    # 定义一个方法,遍历book的auth,然后用列表返回
    def 作者(self, obj):
        return [a.name for a in obj.auth.all()]


admin.site.register(models.Auther, ControlAuther)
admin.site.register(models.Book, ControlBook)

在指定manytomany的model页面,作者选择是可以选择多个的,当然也可以在author中指定这个字段,按住ctrl可以选择多个作者

数据库中自动生成表book_auther,报存两者之间的联系

三.一对一表设计

一对一表使用OneToOneField指定,适用于在原来model设计基础上新增字段

1.表设计使用OneToOneField

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

2.执行python manage.py makemigrations 和python manage.py migrate

3.admin.py进行注册

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]

注意这里跟上两个不一样,MoreInfo继承自StackedInline

ControlCard中指定inlines=[MoreInfo]

carddetail显示的信息在card信息下方

如果MoreInfo继承TabularInline,那么下方显示信息将是横向展示

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值