关系字段分类:一对多、多对多、一对一
一对多
字段:ForeignKey
字段参数:
- to : 设置要关联的表。
- to_field : 设置要关联的表的字段。 默认关联的是表的id。
如果想关联其他字段名称可以使用此字段。
- on_delete: 当删除关联表中的数据时,当前表与其关联的行的行为。
- models.CASCADE :删除关联数据,与之关联也删除。
- models.DO_NOTHING:删除关联数据,引发错误IntegrityError。
- models.PROTECT: 删除关联数据,引发错误ProtectedError。
…
正向查询和反向查询:
注意:
- 正向查询是指从有外键的一方查找另外一方。
- 反向查询是指从没有外键的一方查找有外键的一方。
- 不管是正向还是反向进行对象查找的时候获取的是对象而不是QuerySet集合。
- 正向查询语法:
obj.外键字段(关联字段) -->> 获取对象。
obj.外键字段(关联字段).字段–>> 获取对象对应的字段值。 - 反向查询语法:
obj.表名_set.xxx
外键类型在ORM中用来表示外键关联关系,一般把ForeignKey
字段设置在 '一对多’中’多’的一方。
例如:一个学科对应多个学生,一个学生对应一个学科。
models.py 文件:
from django.db import models
# 学科和学生,一个学科可以对应多个学生,一个学生对应一个学科
class Subject(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.IntegerField()
def __str__(self):
return 'name:{}'.format(self.name)
class Student(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
school = models.CharField(max_length=32)
# 设置外键
# to :表示和哪一个表格进行关联,on_delete : 表示删除策略。
subject = models.ForeignKey(to='Subject', on_delete=models.CASCADE)
def __str__(self):
return 'name:{},age:{}'.format(self.name, self.age)
views.py文件:
from django.shortcuts import render, HttpResponse
from app01 import models
def laowang(request):
#1.查询张三学生学的科目
#正向查询: 从外键一方去查找另外一方。
student_obj = models.Student.objects.get(name='张三')
subject_obj = student_obj.subject # 获取学科对象
print(subject_obj) # name:python
# 获取学科名称
name = subject_obj.name
print(name)
# 反向查询 : 格式: 类名小写_set.xxx
# 2.学python 学科的所有学员。
sub_obj = models.Subject.objects.get(name='python')
student_lst = sub_obj.student_set.all()
print(student_lst)
return HttpResponse('老王好啊')
多对多
用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系。
字段: ManyToManyField
字段参数to: 设置要关联的表
注意: 正向查询和反向查询同一对多规则。
例如:一个老师对应多个学生,一个学生对应多个老师。
models.py 文件:
class Student(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
school = models.CharField(max_length=32)
# 设置外键
# to :表示和哪一个表格进行关联,on_delete : 表示删除策略。
subject = models.ForeignKey(to='Subject', on_delete=models.CASCADE)
def __str__(self):
return 'name:{},age:{}'.format(self.name, self.age)
class Teacher(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
student = models.ManyToManyField(to='Student') # 多对多
def __str__(self):
return 'name:{},age:{}'.format(self.name, self.age)
views.py 文件:
def laowang2(request):
# 正向查询 : 使用关联字段.xxx()
# 1. 老王交过的所有学生
teacher_obj = models.Teacher.objects.get(name='老王')
student_lst = teacher_obj.student.all()
print(student_lst) # <QuerySet [<Student: name:张三,age:20>, <Student: name:旺旺,age:18>]>
for student in student_lst:
print(student.name, student.age)
# 2. 反向查询 : 类名小写_set.xxx()
# 查询 旺旺 被多少老师教过
student_obj = models.Student.objects.get(name='旺旺')
teacher_lst = student_obj.teacher_set.all()
print(teacher_lst)
# <QuerySet [<Teacher: name:老王,age:38>, <Teacher: name:老刘,age:18>]>
return HttpResponse('老王好啊')