web後端--Django學習筆記04
一:“一對多”模型關係
在“多”方模型類建立外來鍵類屬性,關聯“一”方。
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
[email protected]:~$ 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})