Django入门教程

前言

第一章: django快速入门

第二章: django MTV架构

第三章: django视图

第四章: django模板

第五章: django模型

第六章: django后台管理系统

第七章: 项目实战-简易的博客系统

第八章:django表单

第九章:django用户认证系统

第十章:django中的会话

第十一章:django安全

第十二章:django性能优化

第十三章:django实用工具

首页 > Django入门教程 > 第五章: django模型 > 5.5节: 模型的关系字段

5.5节: 模型的关系字段

薯条老师 2020-08-06 07:08:29 233469 0

编辑 收藏

广州番禺Python, Java小班周末班培训

薯条老师在广州做Python和Java的小班培训,一个班最多10人,学员的平均就业薪资有11K不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习。培训的课程有Python爬虫,Python后端开发,Python办公自动化,Python大数据分析,Python量化投资,Python机器学习,Java中高级后端开发。授课详情请点击:http://chipscoco.com/?cate=6

5.5.1 模型中的关系字段

在django中内置了特殊的关系字段,用来定义数据表之间的相关关系,例如主从关系,一对一关系,多对多关系。在django中定义的关系字段主要分为三种类型:ForegnKey,OneToOneFIeld,ManyToManyField。

5.5.2 ForeignKey,OneToOne, ManyToMany

(1) ForeignKey

使用ForeignKey来定义数据表之间的主从关系,ForeignKey表示数据表中的外键,使用外键做主键的数据表被称为主表,具有此外键的表被称为从表。商品与订单号就是一种主从关系,先有商品,才会有所谓的订单号,订单号属于某一个商品。ForeignKey类型的主要参数:

可选参数名

 

描述

to

必传参数,用来指定主表的名称,传递模型的类型名

on_delete

必传参数,用来指定当删除主表中的数据时,从表与其关联的行为,Django提供了以下几个选项:

CASCADE:级联删除,主表中的记录删除时,从表中的数据也会一同删除。

PROJECT:主表中的记录删除时,会引发一个ProtectedError异常。

SET_NULL:主表中的记录删除时,设置从表中的外键为NULL,在定义ForeignKey时必须允许值为空。

SET_DEFAULT:主表中的记录删除时,设置从表中的外键为一个默认值,在定义ForeignKey时必须设置一个默认值。

SET:主表中的记录删除时,通过SET函数来传递一个自定义的值。

to_field

可选参数,设置要关联的主表字段,默认关联的是主表的主键

代码实例:

# 定义一个商品模型,用来作为主表
class Goods(models.Model):
    gid = models.AutoField(primary_key=True)
 
# 定义一个订单模型,用来作为商品表的从表 
class Order(models.Model):

    '''
    商品模型与订单模型是一种主从关系,得先有商品,然后才能有所谓的订单
    在Order模型中定义goods为外键,goods引用自Goods模型中的主键
    设置的on_delete选项为CASCADE, 即当商品删除时,对应的订单也会一同删除。
    '''
    goods = models.ForeignKey(to=Goods, to_field='gid', on_delete=models.CASCADE)

在数据库的数据表中,django会将模型中的外键添加一个_id作为后缀,例如上文代码中的goods,其实际的数据库字段名为:

goods_id

在定义外键时,将主表的名称指定为self, 即将自身作为主表,可以创建一个递归的外键。在评论系统中,一条评论可以被继续评论,如果父级的评论被删除,子级别的评论也应当一同被删除,对于这样的应用场景,可以使用递归外键。

代码实例:

class Comment(models.Model):
    # 定义parent_comment作为递归外键,
    parent_comment = models.ForeignKey(to=self, on_delete=models.CASCADE)

 (2) OneToOneField

使用OneToOne来定义数据表之间的一对一关系,一对一即唯一性,例如在婚姻关系中,人只能有一个妻子(丈夫)。OneToOneField类似于ForeignKey,区别在于OneToOneField的unique参数默认为True。OneToOneField类型的主要参数:

可选参数名

 

描述

to

必传参数,用来指定主表的名称,传递模型的类型名

on_delete

必传参数,用来指定当删除主表中的数据时,从表与其关联的行为。

to_field

可选参数,设置要关联的主表字段,默认关联的是主表的主键

代码实例:

class Wife(models.Model):
    name = models.CharField(max_length=20)
   
class Man(models.Model):
    wife = models.OneToOneField(to=Wife, on_delete=models.SET_NULL, null=True)

在婚姻关系中,一个男人只能有一个妻子。

(3) ManyToManyField

 使用ManyToManyField来定义数据表之间的多对多关系。例如在多对多的关系中,一个dregs woman(渣女)会有多个ambiguous man(暧昧对象), 一个ambiguous man也会同时与多个dregs woman暧昧不清。ManyToManyField类型的主要参数:

可选参数名

 

描述

through

可选参数,用来指定一个中间表,如未进行指定,Django会自动生成一个中间表来进行多对多关系的转换。

through_fields

可选参数,仅在自定义中间表时才使用该参数。through_fields参数接收一个二元元组('field1', 'field2'),field1与field2是中间表中的外键字段,field1指向定义了ManyToManyFIeld字段的模型,field2指向多对多关系中的另外一个模型。

未指定中间表的代码实例:

class AmbiguousMan(models.Model):
    name = models.CharField(max_length=20)
 
class DregsWoman(models.Model):
    name = models.CharField(max_length=20)
    ambiguous_man = models.ManyToManyField(AmbiguousMan)

ManyToManyField的主要操作方法: 

方法名

 

描述

add

添加一个关联的模型对象

remove

删除一个关联的模型对象

all

获取所有的关联对象,返回值为一个QuerySet对象

clear

清空所有的关联对象

在多对多关系中,未定义ManyToManyField字段的模型,django会自动添加一个格式为model_set的管理器。model表示模型名,例如在上文的多对多关系中,AmbiguousMan模型对象会包含一个dregswoman_set的管理器,通过该管理器同样可以调用add,remove,all,clear等方法对其它关系进行操作。

代码实例:

# 实例化一个AmbiguousMan对象
ambiguous_man = AmbiguousMan(name='Backer')
# 执行save方法,将数据写入数据库
ambiguous_man.save()
 
dregs_woman = DregsWoman(name='Lohan')
dregs_woman.save()
dregs_woman.ambiguous_man.add(ambiguous_man)
 
 
# 1.查询渣女的多个暧昧对象
dregs = DregsWoman.objects.get(id=1) 
dregs.ambiguous_man.all()
 
# 2.查询AmbiguousMan的多个DregsMoman:
ambiguous_man = AmbiguousMan.objects.get(id=1)
ambiguous_man.dregswoman_set.all()

对模型进行定义以后,执行模型迁移命令,django会自动生成一个中间表。中间表表名的默认格式:

app_model1_model2

app表示django应用名,model1及model2表示小写的模型名, 假设django应用名为blog,则对上文代码进行模型迁移以后,django创建的中间表为:

blog_dregsmoman_ambiguous_man

在中间表中会定义两个外键字段,分别对多对多关系中的数据表主键进行引用,以进行多对多关系的转换。自定义中间表的代码实例:

class AmbiguousMan(models.Model):
    name = models.CharField(max_length=20)
 
class DregsWoman(models.Model):
    name = models.CharField(max_length=20)
 
    # 使用through参数指定一个中间表
    ambiguous_man = models.ManyToManyField(AmbiguousMan,through='DregsWoman2AmbiguousMan',
                                          through_fields=('dregs_woman','ambiguous_man'))
 

# 自定义中间表,可以在中间表中进行字段扩展
class DregsWoman2AmbiguousMan(models.Model):
 
    id = models.AutoField(primary_key=True)
    # 分别将处于多对多关系中的模型作为外键
    dregs_woman=models.ForeignKey(DregsWoman,on_delete=models.CASCADE,to_field='id')
    ambiguous_man=models.ForeignKey(AmbiguousMan,on_delete=models.CASCADE,to_field='id')
 
    # 定义reason表示暧昧的原因
    reason = models.CharField(max_length=50, blank=True)

通过中间表来添加多对多关系的代码实例:

# 实例化一个AmbiguousMan对象
ambiguous_man = AmbiguousMan(name='Backer')
ambiguous_man.save()
 
# 实例化一个DregsWoman对象
dregs_woman = DregsWoman(name='Lohan')
dregs_woman.save() 
 
# 实例化一个DregsWoman2AmbiguousMan对象
dregsWoman2AmbiguousMan=DregsWoman2AmbiguousMan(dregs_woman=dregs_woman,
                                                ambiguous_man=ambiguous_man, reason='sex')
dregsWoman2AmbiguousMan.save()

5.5.3 最具实力的小班培训

薯条老师在广州做Python和Java的小班培训,一个班最多10人。不在广州的同学可以报名线上直播班,跟线下小班的同学们同步学习。打算参加小班培训的同学,必须遵守薯条老师的学习安排,认真做作业和项目。把知识学好,学扎实,那么找到一份高薪的工作就是很简单的一件事。

(1) Python后端工程师高薪就业班,月薪11K-18K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,包拿Offer
(3) 数据分析高薪就业班,月薪11K-15K, 免费领取课程大纲
(4)
Python大数据挖掘,量化投资就业班,月薪12K-25K,免费领取课程大纲

扫码免费领取Python学习资料:



欢迎 发表评论: