django官方文档详解
  • 编写属于自己的第一个网站
  • 模型与字段类型
  • 关系类型数据字段
  • 模型参数统计说明
关系类型数据字段
Web开发 . 2019/12/09发布 . shanyonggang_web . 我要评论 . 286阅读

关系型字段主要包括多对一、多对多、一对一三种类型的关系数据字段

多对一关系

类似于数据库中的外键

定义一个多对一的关联关系,使用 django.db.models.ForeignKey类。就和其他 Field字段类型一样,只需要在你模型中添加一个值为该类的属性。

举例:

from django.db import models

# Create your models here.
# 三级目录统计
class ThirdIndex(models.Model):
    name = models.CharField(max_length=100,verbose_name='三级目录名称')
    def __str__(self):
        return self.name

# 三级目录下的内容
class ShowInfos(models.Model):
    belong_name = models.ForeignKey(ThirdIndex,on_delete=models.CASCADE,verbose_name='所属三级目录')
    classify = models.CharField(max_length=100,verbose_name='显示内容')
    name = models.CharField(max_length=100,verbose_name='名称')
    text = models.CharField(max_length=100,verbose_name='文本内容')
    def __str__(self):
        return self.name

如上面所述,三级目录可以存在许多内容,但具体内容只能属于某一个三级目录,具体常用参数说明如下:

on_delete=models.CASCADE  必须的参数

limit_choices_to,只能用于Django的ModelForm(Django的表单模块)和admin后台,对其它场合无限制功能。

staff_member = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    limit_choices_to={'is_staff': True},
)

这样定义,则ModelForm的staff_member字段列表中,只会出现那些is_staff=True的Users对象,这一功能对于admin后台非常有用。

related_name ,用于关联对象反向引用模型的名称,如下:

belong_name = models.ForeignKey(ThirdIndex,on_delete=models.CASCADE,verbose_name='所属三级目录',related_name='belong_to_this_column')

related_query_name,用于反向关联查询名,如下:

class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags",
        related_query_name="tag",       # 注意这一行
    )
    name = models.CharField(max_length=255)

# 现在可以使用‘tag’作为查询名了
Article.objects.filter(tag__name="important")

多对多关系

多对多关系也是数据库中非常常见的关系类型,比如一本书可以有好几个作者,一个作者也可以写好几本书,如:

class BookList(models.Model):
    pass
class BookAuthorList(models.Model): 
    books = models.ManyToManyField(BookList)

多对多关系也有对应的所需参数,limit_choices_torelated_name related_query_name三个参数和多对一关系中的参数一样,另外多对多中有个重要的参数through,用来指定多对多关系使用哪个中间模型。

如下:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

through参数在某些使用场景中是必须的,至关重要,请务必掌握!

在中间模型当中有一些限制条件:

  • 你的中间模型要么有且  有一个指向源模型(我们例子当中的 Group )的外键,要么你必须通过 ManyToManyField.through_fields 参数在多个外键当中手动选择一个外键,如果有多个外健且没有用 through_fields 参数选择一个的话,会出现验证错误。对于指向目标模型(我们例子当中的 Person )的外键也有同样的限制。
  • 在一个用于描述模型当中自己指向自己的多对多关系的中间模型当中,可以有两个指向同一个模型的外健,但这两个外健分表代表多对多关系(不同)的两端。如果外健的个数 超过 两个,你必须和上面一样指定 through_fields 参数,要不然会出现验证错误。
  • 在定义模型自己指向自己的多对多关系时,如果使用中间模型,你 必须 定义 symmetrical=False 

一对一关系

当一个对象以某种方式“扩展”另一个对象时,这对该对象的主键非常有用,例如,当你要建立一个有关“位置”信息的数据库时,你可能会包含通常的地址,电话等字段。接着,如果你想接着建立一个关于关于餐厅的数据库,除了将位置数据库当中的字段复制到 Restaurant 模型,你也可以将一个指向 Place OneToOneField 放到 Restaurant 当中(因为餐厅“是一个”地点)。例如:

from django.conf import settings
from django.db import models

# 两个字段都使用一对一关联到了Django内置的auth模块中的User模型
class MySpecialUser(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    supervisor = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='supervisor_of',
    )

跨模块的模型

有时候我们需要从其他APP中导入模型,这时候我们只需要类似引入第三方库的形式引入改模型即可。


  • 有疑问请在下方评论区留言,我会尽快回复。
  • Email私信我: 511248513@qq.com 或添加博主 微信
本文作者:shanyonggang_web
发布时间:2019年12月9日 19:53
许可协议: 署名-非商业性使用 4.0 国际许可协议
知识共享许可协议     转载请保留原文链接及作者
正在加载今日诗词....
您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面的


登录 后回复

当前暂无评论,点击登录来做第一个吃螃蟹的人吧!