当前位置: 首页 > article >正文

django之ForeignKey、OneToOneField 和 ManyToManyField

在Django中,ForeignKeyOneToOneFieldManyToManyField 是用于定义模型之间关系的字段类型。

ForeignKey

ForeignKey 用于定义多对一的关系。例如,一个Employee可以属于一个Department,一个Department可以有多个Employee。

from django.db import models

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

class Employee(models.Model):
    name = models.CharField(max_length=100)
    department = models.ForeignKey(
        Department, 
        on_delete=models.CASCADE,  # 当 Department 被删除时,级联删除关联的 Employee
        related_name='employees',  # 反向关系的名称,可以通过 department.employees.all() 获取所有关联的 Employee
        related_query_name='employee',  # 反向关系的查询名称,可以通过 Department.objects.filter(employee__name='John') 查询
        limit_choices_to={'name__icontains': 'Engineering'},  # 限制可选的 Department 对象
        db_constraint=True,  # 是否在数据库中创建外键约束,默认为 True
        swappable=True,  # 是否允许模型在 INSTALLED_APPS 中被替换,默认为 True
        verbose_name='Department',  # 字段的可读名称
        help_text='Select the department for the employee',  # 帮助文本
        db_index=True  # 是否在数据库中为该字段创建索引,默认为 True
    )
    position = models.CharField(max_length=100, default='Employee')

# 示例数据
engineering = Department.objects.create(name='Engineering')
hr = Department.objects.create(name='Human Resources')

# 创建 Employee 对象
john = Employee.objects.create(name='John Doe', department=engineering)
jane = Employee.objects.create(name='Jane Smith', department=hr)

# 通过反向关系获取所有属于 Engineering 部门的员工
engineering_employees = engineering.employees.all()

# 通过反向查询获取名字为 John 的员工
john_employees = Department.objects.filter(employee__name='John')
  • to: 这里是 Department 模型,表示 Employee 关联到 Department
  • on_delete=models.CASCADE: 当 Department 被删除时,级联删除关联的 Employee
  • related_name='employees': 通过 department.employees.all() 可以获取所有关联的 Employee
  • related_query_name='employee': 通过 Department.objects.filter(employee__name='John') 可以查询关联的 Employee
  • limit_choices_to={'name__icontains': 'Engineering'}: 仅允许选择名称包含 “Engineering” 的 Department 对象。
  • db_constraint=True: 在数据库中创建外键约束。
  • swappable=True: 允许模型在 INSTALLED_APPS 中被替换。
  • verbose_name='Department': 字段的可读名称。
  • help_text='Select the department for the employee': 帮助文本。
  • db_index=True: 在数据库中为该字段创建索引。

OneToOneField

OneToOneField 用于定义一对一的关系。例如,一个用户可以有一个用户配置文件。

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=100)

class UserProfile(models.Model):
    user = models.OneToOneField(
        User, 
        on_delete=models.CASCADE,  # 当 User 被删除时,级联删除关联的 UserProfile
        related_name='profile',  # 反向关系的名称,可以通过 user.profile 获取关联的 UserProfile
        related_query_name='profile',  # 反向关系的查询名称,可以通过 User.objects.filter(profile__bio='Developer') 查询
        limit_choices_to={'username__icontains': 'admin'},  # 限制可选的 User 对象
        db_constraint=True,  # 是否在数据库中创建外键约束,默认为 True
        swappable=True,  # 是否允许模型在 INSTALLED_APPS 中被替换,默认为 True
        primary_key=False,  # 是否将该字段设置为主键,默认为 False
        verbose_name='User',  # 字段的可读名称
        help_text='Select the user for the profile',  # 帮助文本
        db_index=True  # 是否在数据库中为该字段创建索引,默认为 True
    )
    bio = models.TextField()

# 示例数据
user1 = User.objects.create(username='admin_user')
user2 = User.objects.create(username='regular_user')

# 创建 UserProfile 对象
profile1 = UserProfile.objects.create(user=user1, bio='Administrator')
profile2 = UserProfile.objects.create(user=user2, bio='Regular User')

# 通过反向关系获取 user1 的 UserProfile
admin_profile = user1.profile

# 通过反向查询获取 bio 为 'Administrator' 的用户
admin_users = User.objects.filter(profile__bio='Administrator')
  • to: 这里是 User 模型,表示 UserProfile 关联到 User
  • on_delete=models.CASCADE: 当 User 被删除时,级联删除关联的 UserProfile
  • related_name='profile': 通过 user.profile 可以获取关联的 UserProfile
  • related_query_name='profile': 通过 User.objects.filter(profile__bio='Developer') 可以查询关联的 UserProfile
  • limit_choices_to={'username__icontains': 'admin'}: 仅允许选择用户名包含 “admin” 的 User 对象。
  • db_constraint=True: 在数据库中创建外键约束。
  • swappable=True: 允许模型在 INSTALLED_APPS 中被替换。
  • primary_key=False: 不将该字段设置为主键。
  • verbose_name='User': 字段的可读名称。
  • help_text='Select the user for the profile': 帮助文本。
  • db_index=True: 在数据库中为该字段创建索引。

ManyToManyField

ManyToManyField 用于定义多对多的关系。例如,一个学生可以选修多门课程,一门课程可以有多个学生选修。

from django.db import models

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

class Student(models.Model):
    name = models.CharField(max_length=100)
    courses = models.ManyToManyField(
        Course, 
        related_name='students',  # 反向关系的名称,可以通过 course.students.all() 获取所有关联的 Student
        related_query_name='student',  # 反向关系的查询名称,可以通过 Course.objects.filter(student__name='John') 查询
        limit_choices_to={'name__icontains': 'Math'},  # 限制可选的 Course 对象
        db_table='student_courses',  # 自定义中间表的名称
        db_constraint=True,  # 是否在数据库中创建外键约束,默认为 True
        swappable=True,  # 是否允许模型在 INSTALLED_APPS 中被替换,默认为 True
        verbose_name='Courses',  # 字段的可读名称
        help_text='Select the courses for the student',  # 帮助文本
        symmetrical=False,  # 是否为对称关系,默认为 True。通常在自引用多对多关系中使用
        through=None,  # 自定义中间模型
        through_fields=None,  # 指定中间模型的字段
    )

# 示例数据
math_course = Course.objects.create(name='Mathematics')
science_course = Course.objects.create(name='Science')

# 创建 Student 对象
john = Student.objects.create(name='John Doe')
jane = Student.objects.create(name='Jane Smith')

# 关联课程
john.courses.add(math_course)
jane.courses.add(math_course, science_course)

# 通过反向关系获取所有选修 Mathematics 课程的学生
math_students = math_course.students.all()

# 通过反向查询获取名字为 John 的学生
john_students = Course.objects.filter(student__name='John')
  • to: 这里是 Course 模型,表示 Student 关联到 Course
  • related_name='students': 通过 course.students.all() 可以获取所有关联的 Student
  • related_query_name='student': 通过 Course.objects.filter(student__name='John') 可以查询关联的 Student
  • limit_choices_to={'name__icontains': 'Math'}: 仅允许选择名称包含 “Math” 的 Course 对象。
  • db_table='student_courses': 自定义中间表的名称。
  • db_constraint=True: 在数据库中创建外键约束。
  • swappable=True: 允许模型在 INSTALLED_APPS 中被替换。
  • verbose_name='Courses': 字段的可读名称。
  • help_text='Select the courses for the student': 帮助文本。
  • symmetrical=False: 这里设置为 False,因为这是一个非对称关系(学生和课程的关系不是对称的)。
  • through=None: 不使用自定义中间模型。
  • through_fields=None: 不指定中间模型的字段。

http://www.kler.cn/a/291096.html

相关文章:

  • 滚珠花键的保养与维护方法
  • Docker:Dockerfile(补充四)
  • Android Java Ubuntu系统如何编译出 libopencv_java4.so
  • git使用和gitlab部署
  • 艾体宝案例丨CircleCI 助力 ANA Systems 打造高效 CI/CD 模型
  • 【Linux进程】进程间的通信
  • 惠中科技综合光伏清洗技术:引领绿色清洁新时代
  • 【后端开发】PHP、go语言、Java、C++、Linux开发等急招中......
  • Windows电脑获取目录及子目录结构及包含文件名的命令
  • notepad++将换行替换成空
  • JS设计模式之“神奇的魔术师” - 简单工厂模式
  • 【Python篇】PyQt5 超详细教程——由入门到精通(中篇一)
  • 栈和队列的习题详解(2):用队列实现栈
  • 注册中心技术选型
  • 将Google Chrome或Microsoft Edge浏览器的地址栏隐藏的方法
  • 【GPT】Coze使用开放平台接口-【1】创建插件
  • 省钱的开源项目「GitHub 热点速览」
  • 智能未来:低代码与AI如何重塑企业应用开发
  • PostgreSQL添加远程用户访问
  • 经典大语言模型解读(2):生成式预训练的先锋GPT-1
  • 【RAG】LongRAG:利用长上下文LLMs增强检索增强生成
  • 假期学习----iOS多线程
  • 神经网络算法 - 一文搞懂模型预训练Pre-training
  • WPS 5亿用户受威胁:APT-C-60利用WPS Office漏洞发动间谍攻击
  • AI相机将用于检测区域内使用手机的司机
  • 『功能项目』主角身旁召唤/隐藏坐骑【20】