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()
相关推荐
小瓦码J码1 小时前
PostgreSQL表名超长踩坑记
数据库·postgresql
yhyyht1 小时前
InfluxDB入门记录(三)flux-dsl
数据库·后端
IvorySQL19 小时前
PostgreSQL 技术日报 (3月9日)|EXPLAIN ANALYZE 计时优化与复制语法讨论
数据库·postgresql·开源
stark张宇1 天前
MySQL 核心内幕:从索引原理、字段选型到日志机制与外键约束,一篇打通数据库任督二脉
数据库·mysql·架构
倔强的石头_1 天前
融合数据库架构实践:关系型、JSON与全文检索的“一库多能”深度解析
数据库
星辰员1 天前
KingbaseES数据库:ksql 命令行用户与权限全攻略,从创建到删除
数据库
华仔啊2 天前
千万别给数据库字段加默认值 null!真的会出问题
java·数据库·后端
随风飘的云3 天前
MySQL的慢查询优化解决思路
数据库
IvorySQL3 天前
PostgreSQL 技术日报 (3月7日)|生态更新与内核性能讨论
数据库·postgresql·开源
赵渝强老师3 天前
【赵渝强老师】金仓数据库的数据文件
数据库·国产数据库·kingbase·金仓数据库