一文看懂DjangoOrm中的一对一,一对多,多对多关系

在Django中,模型(Model)定义了你的数据库结构和数据操作的Python类。Django ORM(对象关系映射)提供了一种方式来处理数据库表之间的关系。以下是关于Django模型中一对一(One-to-One)、一对多(One-to-Many)和多对多(Many-to-Many)关系的详细解说:

一对一关系 (One-to-One)

用途:当两个模型之间有很强的关联性,且一个模型的实例对应另一个模型的单一实例时使用。

定义

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(models.Model):
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)
  • OneToOneField 创建了一个一对一的链接。
  • on_delete=models.CASCADE 意味着当Place被删除时,关联的Restaurant也会被删除。
  • primary_key=True 表示Restaurant模型使用Place的外键作为主键。

使用:

# 创建一个地方
p = Place(name='Demon Dogs', address='944 W. Fullerton')
p.save()

# 创建一个餐馆,并将它与这个地方关联
r = Restaurant(place=p, serves_hot_dogs=True, serves_pizza=False)
r.save()

# 通过餐馆访问地点
print(r.place.name)  # 输出:Demon Dogs

# 通过地点访问餐馆
restaurant = p.restaurant  # 注意这里是小写,因为Django会自动添加一个反向关系

一对多关系 (One-to-Many)

用途:当一个模型的实例可以关联多个另一个模型的实例时使用。

定义

from django.db import models

class Reporter(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE, related_name='articles')
  • ForeignKey 字段在Article模型中定义了到Reporter的外键。
  • on_delete=models.CASCADE 表示当一个Reporter被删除时,所有关联的Article也会被删除。
  • db_column:这指定了数据库中实际使用的列名。如果不指定,Django会自动生成一个默认的名称(通常是外键字段名加上_id)。
class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE, db_column='reporter_id')
  • related_name:这是一个非常重要的参数,它定义了从Reporter模型访问其所有Article实例的方法名。默认情况下,Django会使用模型名的小写加_set来作为反向关系的名字,但你可以通过related_name来指定一个自定义名称。在上面的例子中,我们使用了articles,所以你可以这样访问文章:reporter.articles.all()

使用

# 创建一个记者
r = Reporter(first_name='John', last_name='Smith')
r.save()

# 创建几篇文章,并关联到记者
a1 = Article(headline="This is a test", pub_date=date(2005, 7, 27), reporter=r)
a1.save()
a2 = Article(headline="This is another test", pub_date=date(2005, 7, 28), reporter=r)
a2.save()

# 通过记者访问所有文章
reporter_articles = r.article_set.all()  # 注意这里使用了模型名的小写加'_set'

多对多关系 (Many-to-Many)

用途:当一个模型的实例可以关联多个另一个模型的实例,反之亦然。

定义

class Publication(models.Model):
    title = models.CharField(max_length=30)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField(Publication)

  • ManyToManyField 字段在Article模型中定义了到Publication的多对多关系。
  • Django会自动创建一个中间表来管理这种关系。

使用

# 创建出版物
p1 = Publication(title="The Python Journal")
p1.save()
p2 = Publication(title="Science News")
p2.save()

# 创建文章
a = Article(headline="Django lets you build Web apps easily")
a.save()
a.publications.add(p1)  # 将文章添加到第一个出版物
a.publications.add(p2)  # 现在文章属于两个出版物

# 通过出版物访问所有文章
publication_articles = p1.article_set.all()

# 通过文章访问所有出版物
article_publications = a.publications.all()

 

总结

  • 一对一关系适用于强关联的场景,通常用于模型的扩展。
  • 一对多关系是数据库设计中最常见的关系类型,适用于一个实体可以拥有多个相关实体的场景。
  • 多对多关系允许两边的模型实例彼此关联,适用于复杂的关系网络。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值