一:“一对多”模型关系
在“多”方模型类创建外键类属性,关联“一”方。
class School(models.Model): # "一"方模型 pass
class Student(models.Model): # "多"方模型 stuschool = models.ForeignKey(School,on_delete=models.CASCADE)
1.创建“一”方模型对象
school1 = School.objects.create(name="清华大学",address="北京",establish_date=date(1901,4,10))
2.创建“多”方模型对象
方式一:通过“一”方的实例化对象关联stu1 = Student.objects.create(name="张清华",sex='男',score=83.5,stuschool=school1)
方式二:通过对应表的外键关联stu2 = Student.objects.create(name="李清华",sex="女",score=89,stuschool_id=1)
方式三:通过“一”方添加对象stu3 = school1.student_set.create(name="赵清华",sex='女',score=93)
3.从“一”方查询“多”方
使用“多”方模型类小写_set,作为“一”方容器。students = school1.student_set.all()
4.从“多”方查询“一”方
使用“多”方外键属性直接获取对应的“一”方实例school = stu1.stuschool
5.代码演示
1、models
from django.db import models class School(models.Model): name = models.CharField(max_length=20) address = models.CharField(max_length=30) establish_date = models.DateField() def __str__(self): return self.name class Meta: db_table = 'schools' ordering = ('establish_date',) class Student(models.Model): name = models.CharField(max_length=20) sex = models.CharField(max_length=10) score = models.FloatField() stuschool = models.ForeignKey(School,on_delete=models.CASCADE) def __str__(self): return self.name class Meta: db_table = 'students' ordering = ('-score','-id')
2、Terminal
C:\python\DjangoDay41>python manage.py startapp one2ma ngapp C:\python\DjangoDay41>python manage.py makemigrations Migrations for 'one2mangapp': one2mangapp\migrations\0001_initial.py - Create model School - Create model Student C:\python\DjangoDay41>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, hom ework, one2mangapp, sessions Running migrations: Applying one2mangapp.0001_initial... OK C:\python\DjangoDay41>python manage.py shell Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51 ) [MSC v.1914 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for m ore information. (InteractiveConsole) >>> from one2mangapp.models import * >>> from datetime import date >>> school1 = School.objects.create(name="清华大学",address="北京",establish_date=date(1901,4,10)) >>> stu1 = Student.objects.create(name="张清华",sex='男',score=83.5,stuschool=school1) >>> stu2 = Student.objects.create(name="李清华",sex="女",score=89,stuschool_id=1) >>> stu3 = school1.student_set.create(name="赵清华",sex='女 ',score=93) >>> stu4 = school1.student_set.create(name="王清华",sex='女 ',score=85) >>> school2 = School.objects.create(name="北京大学",address ="北京",establish_date=date(1903,3,15)) >>> schools = School.objects.all() >>> for s in schools: ... print(s) ... 清华大学 北京大学 >>> students = Student.objects.all() >>> for s in students: ... print(s) ... 赵清华 李清华 王清华 张清华 >>> schools = School.objects.all() >>> for s in schools: ... print(s) ... 清华大学 北京大学 >>> students = Student.objects.all() >>> for s in schools: ... print(s) ... 清华大学 北京大学 >>> for s in students: ... print(s) ... 赵清华 李清华 王清华 张清华 >>> school1 = School.objects.get(id=1) >>> school1 <School: 清华大学> >>> students = school1.student_set.all() >>> for s in students: ... print(s) ... 赵清华 李清华 王清华 张清华 >>> school2 = Student.objects.get(id=2) >>> school2 <Student: 李清华> >>> school2 = School.objects.get(id=2) >>> school2 <School: 北京大学> >>> Student.objects.create(name='刘备大',sex='男',score=88, stuschool=school2) <Student: 刘备大> >>> Student.objects.create(name='王备大',sex='男',score=88, stuschool=school2) <Student: 王备大> >>> students = school2.student_set.all() >>> for s in students: ... print(s) ... 王备大 刘备大 >>> stu1 = Student.objects.get(id=5) >>> stu1 <Student: 刘备大> >>> stu1.stuschool <School: 北京大学>
二:“一对一”模型关系
在维护关系的“一方”使用models.OneToOneField(“另一个一方模型类名称”,on_delete=models.CASCADE) class Person(models.Model): pass
class IDCard(models.Model): cardno = models.CharField(max_length=20,primary_key=True) per = models.OneToOneField(Person,on_delete=models.CASCADE) # 一对一关联
1.创建不负责维护关系的“一方”
per1 = Person.objects.create(name="张三",age=20,ismarried=False)
2.创建负责维护关系的“一方”
方式一:通过另一方的实例化对象关联card1 = IDCard.objects.create(cardno='zs123456',per=per1)
方式二:通过表中的唯一外键关联card2 = IDCard.objects.create(cardno='ls123456',per_id=2)
3.从“主动一方”查询“被动一方”
通过“被动一方”模型类名的小写形式card1 = per1.idcard
4.从“被动一方”查询“主动一方”
通过“被动一方”的维护关系的类属性直接查询到“主动一方”per1 = card1.per
5.删除记录
per = Person.objects.get(id=2) # 查询2号记录per.delete() # 删除2号记录(级联删除)
6.代码演示
1、models
from django.db import models class Person(models.Model): name = models.CharField(max_length=10) age = models.IntegerField() ismarried = models.BooleanField() def __str__(self): return self.name class Meta: db_table = 'person' class IDCard(models.Model): cardno = models.CharField(max_length=20,primary_key=True) per = models.OneToOneField(Person,on_delete=models.CASCADE) # 一对一关联 def __str__(self): return self.cardno class Meta: db_table = 'cards'
2、Terminal
C:\python\DjangoDay41>python manage.py startapp one2oneapp C:\python\DjangoDay41>python manage.py makemigrations Migrations for 'one2oneapp': one2oneapp\migrations\0001_initial.py - Create model IDCard - Create model Person - Add field per to idcard C:\python\DjangoDay41>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, homework , one2mangapp, one2oneapp, sessions Running migrations: Applying one2oneapp.0001_initial... OK C:\python\DjangoDay41>python manage.py shell Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MS C v.1914 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more i nformation. (InteractiveConsole) >>> from one2oneapp.models import * >>> per1 = Person.objects.create(name="张三",age=20,ismarri ed=False) >>> per1 = Person.objects.create(name="李娟",age=20,ismarri ed=True)
三:“多对多”关系
在某个“多方”通过 models.ManyToManyField(另一个多方模型类,through="中间关系模型类") 设置模型之间的关系。
在中间模型类中至少有两个外键类属性,分别关联两个多方模型。
class Student(models.Model): pass
class Course(models.Model): name = models.CharField(max_length=10) stu = models.ManyToManyField(Student,through="Student_Course") # 多对多关系
class Student_Course(models.Model): # 中间模型,负责维护两个“多方”模型 student = models.ForeignKey(Student,on_delete=models.CASCADE) # 关联Student模型的外键 course = models.ForeignKey(Course,on_delete=models.CASCADE) # 关联Course模型的外键 score = models.FloatField()
1.添加不负责维护关系的“多方”
stu1 = Student.objects.create(name="张三",age=20,sex='男')
2.创建负责关联的“多方”
course1 = Course.objects.create(name='数学')
3.创建第三方关系
使用实例化对象关联sc1 = Student_Course.objects.create(student=stu1,course=course1,score=85)
使用外键值关联sc3 = Student_Course.objects.create(student_id=3,course_id=1,score=69)
4.从不负责的多方查询另一个多方
例如:1号学生选的课程 student1 = Student.objects.get(id=1) courses = student1.course_set.all() # 对方模型类小写_set
5.从负责关联的多方查询另一个多方
例如:查询选择2号课程的学生course2 = Course.objects.get(id=2)students = course2.stu.all() # stu为关联类属性
6.代码演示
1、models
from django.db import models class Student(models.Model): name = models.CharField(max_length=10) age = models.IntegerField() sex = models.CharField(max_length=10) def __str__(self): return self.name class Meta: db_table = 'many_students' class Course(models.Model): name = models.CharField(max_length=10) stu = models.ManyToManyField(Student,through="Student_Course") # 多对多关系 def __str__(self): return self.name class Meta: db_table = 'courses' class Student_Course(models.Model): # 中间模型,负责维护两个“多方”模型 student = models.ForeignKey(Student,on_delete=models.CASCADE) # 关联Student模型的外键 course = models.ForeignKey(Course,on_delete=models.CASCADE) # 关联Course模型的外键 score = models.FloatField() class Meta: db_table = 'student_course'
2、MySQL
ywh@ubuntu:~$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.7.23-0ubuntu0.16.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use mydb Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------------------+ | Tables_in_mydb | +----------------------------+ | articles | | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | cakes | | cards | | django_admin_log | | django_content_type | | django_migrations | | django_session | | myapp_product | | person | | schools | | students | | workers | +----------------------------+ 18 rows in set (0.00 sec) mysql> show tables; +----------------------------+ | Tables_in_mydb | +----------------------------+ | articles | | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | cakes | | cards | | courses | | django_admin_log | | django_content_type | | django_migrations | | django_session | | many_students | | myapp_product | | person | | schools | | student_course | | students | | workers | +----------------------------+ 21 rows in set (0.00 sec) mysql> desc student_course; +------------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | score | double | NO | | NULL | | | course_id | int(11) | NO | MUL | NULL | | | student_id | int(11) | NO | MUL | NULL | | +------------+---------+------+-----+---------+----------------+ 4 rows in set (0.01 sec) mysql> show creat table student_course; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that nds to your MySQL server version for the right syntax to use near 'creat table sourse' at line 1 mysql> show create table student_course; +----------------+------------------------------------------- | Table | Create Table | student_course | CREATE TABLE `student_course` ( `id` int(11) NOT NULL AUTO_INCREMENT, `score` double NOT NULL, `course_id` int(11) NOT NULL, `student_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `student_course_course_id_16fdadee_fk_courses_id` (`course_id`), KEY `student_course_student_id_b55d2772_fk_many_students_id` (`student_id`), CONSTRAINT `student_course_course_id_16fdadee_fk_courses_id` FOREIGN KEY (`cou REFERENCES `courses` (`id`), CONSTRAINT `student_course_student_id_b55d2772_fk_many_students_id` FOREIGN KEent_id`) REFERENCES `many_students` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | +----------------+------------------------------------------- 1 row in set (0.01 sec) mysql> select * from django_migrations; +----+--------------+------------------------------------------+--------------------+ | id | app | name | applied | +----+--------------+------------------------------------------+--------------------+ | 1 | contenttypes | 0001_initial | 2018-10-07 09:0333 | | 2 | auth | 0001_initial | 2018-10-07 09:0574 | | 3 | admin | 0001_initial | 2018-10-07 09:0514 | | 4 | admin | 0002_logentry_remove_auto_add | 2018-10-07 09:0510 | | 5 | admin | 0003_logentry_add_action_flag_choices | 2018-10-07 09:0498 | | 6 | contenttypes | 0002_remove_content_type_name | 2018-10-07 09:0023 | | 7 | auth | 0002_alter_permission_name_max_length | 2018-10-07 09:0994 | | 8 | auth | 0003_alter_user_email_max_length | 2018-10-07 09:0963 | | 9 | auth | 0004_alter_user_username_opts | 2018-10-07 09:0950 | | 10 | auth | 0005_alter_user_last_login_null | 2018-10-07 09:0923 | | 11 | auth | 0006_require_contenttypes_0002 | 2018-10-07 09:0917 | | 12 | auth | 0007_alter_validators_add_error_messages | 2018-10-07 09:0910 | | 13 | auth | 0008_alter_user_username_max_length | 2018-10-07 09:0883 | | 14 | auth | 0009_alter_user_last_name_max_length | 2018-10-07 09:0827 | | 15 | myapp | 0001_initial | 2018-10-07 09:0813 | | 16 | sessions | 0001_initial | 2018-10-07 09:0789 | | 17 | myapp | 0002_article | 2018-10-08 02:4833 | | 18 | managerapp | 0001_initial | 2018-10-09 06:2514 | | 19 | homework | 0001_initial | 2018-10-10 01:1268 | | 20 | one2mangapp | 0001_initial | 2018-10-10 04:4523 | | 21 | one2oneapp | 0001_initial | 2018-10-11 14:0905 | | 22 | many2manyapp | 0001_initial | 2018-10-26 01:1869 | +----+--------------+------------------------------------------+--------------------+ 22 rows in set (0.00 sec) mysql> select * from many_students; +----+--------+-----+-----+ | id | name | age | sex | +----+--------+-----+-----+ | 1 | 张三 | 20 | 男 | | 2 | 李四 | 22 | 男 | | 3 | 李四 | 22 | 男 | | 4 | 王五 | 26 | 男 | +----+--------+-----+-----+ 4 rows in set (0.01 sec) mysql> select * from courses; +----+--------+ | id | name | +----+--------+ | 1 | 数学 | | 2 | 英语 | | 3 | python | +----+--------+ 3 rows in set (0.02 sec) mysql> select * from student_course; +----+-------+-----------+------------+ | id | score | course_id | student_id | +----+-------+-----------+------------+ | 1 | 85 | 1 | 1 | | 3 | 95 | 3 | 2 | | 4 | 90 | 3 | 4 | | 5 | 80 | 2 | 3 | +----+-------+-----------+------------+ 4 rows in set (0.00 sec) mysql> select * from student_course; +----+-------+-----------+------------+ | id | score | course_id | student_id | +----+-------+-----------+------------+ | 1 | 85 | 1 | 1 | | 3 | 95 | 3 | 2 | | 4 | 90 | 3 | 4 | | 5 | 80 | 2 | 3 | | 6 | 75 | 2 | 2 | +----+-------+-----------+------------+ 5 rows in set (0.00 sec) mysql> select * from many_students; +----+--------+-----+-----+ | id | name | age | sex | +----+--------+-----+-----+ | 1 | 张三 | 20 | 男 | | 2 | 李四 | 22 | 男 | | 3 | 李四 | 22 | 男 | | 4 | 王五 | 26 | 男 | +----+--------+-----+-----+ 4 rows in set (0.00 sec) mysql> select * from many_students; +----+--------+-----+-----+ | id | name | age | sex | +----+--------+-----+-----+ | 1 | 张三 | 20 | 男 | | 3 | 李四 | 22 | 男 | | 4 | 王五 | 26 | 男 | +----+--------+-----+-----+ 3 rows in set (0.01 sec) mysql> select * from student_course; +----+-------+-----------+------------+ | id | score | course_id | student_id | +----+-------+-----------+------------+ | 1 | 85 | 1 | 1 | | 4 | 90 | 3 | 4 | | 5 | 80 | 2 | 3 | +----+-------+-----------+------------+ 3 rows in set (0.00 sec) mysql> select * from courses; +----+--------+ | id | name | +----+--------+ | 1 | 数学 | | 2 | 英语 | | 3 | python | +----+--------+ 3 rows in set (0.00 sec) mysql> select * from courses; +----+--------+ | id | name | +----+--------+ | 1 | 数学 | | 2 | 英语 | +----+--------+ 2 rows in set (0.00 sec)
3、Terminal
Microsoft Windows [版本 10.0.17763.55] (c) 2018 Microsoft Corporation。保留所有权利。pytho C:\python\DjangoDay41>python manage.py makemigrations Migrations for 'many2manyapp': many2manyapp\migrations\0001_initial.py - Create model Course - Create model Student - Create model Student_Course - Add field stu to course C:\python\DjangoDay41>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, hom ework, many2manyapp, one2mangapp, one2oneapp, sessions Running migrations: Applying many2manyapp.0001_initial... OK C:\python\DjangoDay41>python manage.py shell Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51 ) [MSC v.1914 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for m ore information. (InteractiveConsole) >>> from many2manyapp.models import * >>> >>> stu1 = Student.objects.create(name="张三",age=20,s ex='男') >>> course1 = Course.objects.create(name='数学') >>> sc1 = Student_Course.objects.create(student=stu1,c ourse=course1,score=85) >>> stu1 = Student.objects.create(name="李四",age=22,s ex='男') >>> stu2 = Student.objects.create(name="李四",age=22,s ex='男') >>> stu3 = Student.objects.create(name="王五",age=26,s ex='男') >>> course2 = Course.objects.create(name='英语') >>> course3 = Course.objects.create(name='python') >>> sc2 = Student_Course.objects.create(student=stu1,c ourse=course3,score=95) >>> sc3 = Student_Course.objects.create(student=stu3,c ourse=course3,score=90) >>> sc3 = Student_Course.objects.create(student=stu2,c ourse=course2,score=80) >>> sc2 = Student_Course.objects.create(student=stu1,c ourse=course2,score=75) >>> student1 = Student.objects.get(id=1) >>> student1 = Student.objects.get(id=2) >>> courses = student1.course_set.all() >>> for course in courses: ... print(course) ... 英语 python >>> student1 = Student.objects.get(id=3) >>> courses = student1.course_set.all() >>> for course in courses: ... print(course) ... 英语 >>> >>> course2 = Course.objects.get(id=2) >>> students = course2.stu.all() >>> for i in students: ... print(i.name) ... 李四 李四 >>> students = course3.stu.all() >>> for i in students: ... print(i.name) ... 李四 王五 >>> student1 = Student.objects.get(id=2) >>> student1.delete() (3, {'many2manyapp.Student_Course': 2, 'many2manyapp.S tudent': 1}) >>> course = Course.objects.get(id=3) >>> course.delete() (2, {'many2manyapp.Student_Course': 1, 'many2manyapp.C ourse': 1})