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()
相关推荐
zuYM4g7Dp22 分钟前
NoSql数据库设计心得
数据库·nosql
睡不醒男孩0308232 小时前
第七篇:揭秘 PostgreSQL 数据库内核级管控:CLup 深度架构设计与高可用底座技术白皮书
数据库·postgresql·clup
cmes_love3 小时前
Level 2逐笔成交历史数据下载方法笔记
数据库·笔记·oracle
swordbob3 小时前
MySQL字符集陷阱:从Oracle迁移踩坑到utf8mb4强制规范
数据库·sql
牛油果子哥q3 小时前
【C++ STL string 】C++ STL string 终极精讲:底层原理、内存机制、全套API、深浅拷贝、易错坑点与工程实战规范
数据库·c++
十五年专注C++开发3 小时前
MySql中各种功能用sql语句实现总结
数据库·sql·mysql
数据库小学妹4 小时前
AI时代数据库怎么选?多模融合、数据统一存储与选型实战指南
数据库·人工智能·经验分享·ai
Albert Edison4 小时前
【Redis】Centos7.9 安装 Redis 5 教程
数据库·redis·缓存
云计算磊哥@4 小时前
运维开发宝典026-MySQL02数据库表操作
运维·数据库·运维开发
小二·4 小时前
Redis 内存溢出(OOM)排查与恢复实战
数据库·redis·bootstrap