Django中 model 一对一 一对多 多对多关系 关联

在 Django ORM 中,关联关系用于定义模型之间的关系。Django 提供了多种关联类型,主要包括一对一、一对多和多对多关系。以下是每种关联关系的详细说明及用法:

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

使用 OneToOneField 定义一对一关系,表示一个模型实例与另一个模型实例一一对应。

示例

python 复制代码
from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField('auth.User', on_delete=models.CASCADE)
    bio = models.TextField()

# 使用示例
# 假设已经有一个 User 实例 user
profile = UserProfile.objects.create(user=user, bio="This is the bio")

on_delete:定义相关联对象被删除时的行为,常用选项:

  • CASCADE: 删除相关对象。
  • SET_NULL: 设置为 NULL
  • PROTECT: 阻止删除。
  • SET_DEFAULT: 设置为默认值。

2. 一对多关系(ForeignKey)

使用 ForeignKey 定义一对多关系,表示多个模型实例可以指向同一个父对象。

示例

python 复制代码
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')

# 使用示例
author = Author.objects.create(name="Author Name")
book1 = Book.objects.create(title="Book 1", author=author)
book2 = Book.objects.create(title="Book 2", author=author)

# 通过 related_name 获取所有书籍
books = author.books.all()
  • related_name:反向访问字段的名称。
  • on_delete:定义关联对象删除时的行为。

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

使用 ManyToManyField 定义多对多关系,表示多个对象可以互相关联。

示例

python 复制代码
class Student(models.Model):
    name = models.CharField(max_length=100)

class Course(models.Model):
    title = models.CharField(max_length=100)
    students = models.ManyToManyField(Student, related_name='courses')

# 使用示例
student1 = Student.objects.create(name="Student 1")
student2 = Student.objects.create(name="Student 2")
course = Course.objects.create(title="Math")
course.students.add(student1, student2)

# 反向获取学生的课程
student_courses = student1.courses.all()

4. 关联关系的高级用法

(1)自关联

模型可以与自身关联:

python 复制代码
class Employee(models.Model):
    name = models.CharField(max_length=100)
    manager = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)

# 示例
manager = Employee.objects.create(name="Manager")
employee = Employee.objects.create(name="Employee", manager=manager)
(2)通过中间表的多对多关系

自定义中间表可以使用 through 参数:

python 复制代码
class Membership(models.Model):
    student = models.ForeignKey('Student', on_delete=models.CASCADE)
    course = models.ForeignKey('Course', on_delete=models.CASCADE)
    date_joined = models.DateField()

class Course(models.Model):
    title = models.CharField(max_length=100)
    students = models.ManyToManyField('Student', through='Membership')

class Student(models.Model):
    name = models.CharField(max_length=100)

5. 查询方法

Django 提供了丰富的查询接口:

  • 正向查询:通过外键字段查询。
  • 反向查询:通过 related_name_set 进行查询。
python 复制代码
# 正向查询
book = Book.objects.get(id=1)
author = book.author

# 反向查询
author = Author.objects.get(id=1)
books = author.books.all()
相关推荐
数据智能老司机7 小时前
CockroachDB权威指南——CockroachDB SQL
数据库·分布式·架构
数据智能老司机8 小时前
CockroachDB权威指南——开始使用
数据库·分布式·架构
松果猿8 小时前
空间数据库学习(二)—— PostgreSQL数据库的备份转储和导入恢复
数据库
无名之逆8 小时前
Rust 开发提效神器:lombok-macros 宏库
服务器·开发语言·前端·数据库·后端·python·rust
s9123601018 小时前
rust 同时处理多个异步任务
java·数据库·rust
数据智能老司机8 小时前
CockroachDB权威指南——CockroachDB 架构
数据库·分布式·架构
hzulwy9 小时前
Redis常用的数据结构及其使用场景
数据库·redis
程序猿熊跃晖9 小时前
解决 MyBatis-Plus 中 `update.setProcInsId(null)` 不生效的问题
数据库·tomcat·mybatis
强化生物科研小助手9 小时前
CAS:47623-98-3,DiSBAC2(3)一种慢反应的膜电位敏感探针
django·html·pygame
Three~stone10 小时前
MySQL学习集--DDL
数据库·sql·学习