在 Django ORM 中,关联关系用于定义模型之间的关系。Django 提供了多种关联类型,主要包括一对一、一对多和多对多关系。以下是每种关联关系的详细说明及用法:
1. 一对一关系(One-to-One)
使用 OneToOneField
定义一对一关系,表示一个模型实例与另一个模型实例一一对应。
示例:
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
定义一对多关系,表示多个模型实例可以指向同一个父对象。
示例:
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
定义多对多关系,表示多个对象可以互相关联。
示例:
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)自关联
模型可以与自身关联:
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
参数:
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
进行查询。
# 正向查询
book = Book.objects.get(id=1)
author = book.author
# 反向查询
author = Author.objects.get(id=1)
books = author.books.all()