ORM操作的一对多、多对多、一对一

一、主要函数

############################主要函数#############################
fileter()			#返回符合指定条件的QuerySet
exclude()			#返回不符合指定条件的QuerySet
order_by()			#串接到QuerySet之后,针对某一指定的字段进行排序
all()				#返回所有的QuerySet
get()				#获取指定符合条件的唯一元素,如果找不到或有多个符合条件,都会产生exception
first()				#获取第一个元素
last()				#获取最后一个元素
aggregate()			#用来计算数据项的聚合函数
exists()			#用来检查是否存在某指令条件的记录,通常附加在filter()后面
update()			#用来快速更新某数据记录中的字段内容
delete()			#删除指定的记录
iexact()			#不区分大小写的条件设置
contains()			#设置条件为含有某一字符串就符合,比如SQL语句中的LIKE 和 ILIKE
icontains()			#设置条件为含有某一字符串就符合,比如SQL语句中的LIKE 和 ILIKE
in()				#提供一个列表,只要符合列表中的任何一个值均可
gt()				#大于
gte()				#大于等于
lt()				#小于	
lte()				#小于等于


python manage.py makemigrations	#创建模型
python manage.py migrate		#创建表
python manage.py shell			#进入python交互环境
python manage.py dbshell		#进入当前连接的数据库
python manage.py runserver		#开启Django
python manage.py createsuperuser    #创建超级用户(密码需要数字和字母,至少八位)

python manage.py startapp myapp    #创建名字为myapp的应用

 

 二、方法使用

#############################方法使用###################################
第一步:先在app下的models中创建某个(多个)对象
from django.db import models

class Student(models.Model):
	name = models.CharField(max_length=20)
	sex = models.CharField(max_length=10)
	score = models.FloatField()

	
第二步:在交互环境下(Terminal)进行操作
python manage.py makemigrations
python manage.py migrate

python manage.py shell
from app.models import Student

#创建记录	(与插入操作相同)
	stu = Student.objects.create(name='jerry',sex='男',score=88)
	stu.save()					#将数据存储到数据库中。。
	#上面代码等同于下面
	Student.objects.create(name='jerry',sex='男',score=88)

#插入操作	(通过程序向表中插入记录)
    stu = Student(name='tom',sex='男',score=83.5)
    stu.save()

#更新操作	(使用与数据表中对应的对象,调用save()方法)
    stu.score = 90		#此方法不能更新id
    stu.save()
	#下面方法更新id
	Student.objects.filter(id=原来id).update(id=修改后的id)

#查询操作
    Student.objects.all()	#查询所有,返回结果集对象(QuerySet),其包含了所有记录	   
							#返回的结果集对象可以通过for...in遍历,也可以使用索引访问其中的某个元素。  
	Student.objects.get(id=1)	#根据id查询单条记录。。。只能返回一条记录,如果多于1条或没有查询到则引发异常
	Student.objects.filter(score=90)	#根据过滤条件查询。。。返回的结果集对象可以通过for...in遍历,也可以使用索引访问其中的某个元素。
	Student.objects.filter(id__in=(8,9))	#通过__in方法查询id=8或id=9的对象
	Student.objects.filter(id__ge=9)		#通过__ge方法查询id大于9的对象
	Student.objects.filter(id__gte=9)		#通过__ge方法查询id大于等于9的对象
	Student.objects.filter(id__lt=9)		#通过__ge方法查询id小于9的对象
	Student.objects.filter(id__lte=9)		#通过__ge方法查询id小于等于9的对象
	
#删除操作   
	Student.objects.get(id=1).delete()			#单条删除
	Student.objects.all().delete()  			#多条删除
	Student.objects.filter(score=60).delete()	#删除score=60的所有学生

 实例一:

#################实例一###################
D:\django\DjangoDay3>python manage.py shell

>>> from modelapp.models import Student
>>> stu1 = Student(name='tom',sex='男',score=80.5)	#插入数据,并且实例化对象stu1
>>> stu1.save()						#保存数据到数据库
>>> stu1.score = 90					#修改score
>>> stu1.save()						#保存修改

>>> stu2 = Student(name='alice',sex='女',score=90)
>>> stu2.save()
>>> Student.objects.all()				#查看所有数据
<QuerySet [<Student: Student object (1)>, <Student: Student object (2)>]>

>>> stu3 = Student(name='dd',sex='女',score=95)
>>> stu3.save()

>>> Student.objects.all()				#查看所有Student对象
<QuerySet [<Student: Student object (1)>, <Student: Student object (2)>, <Student: Student object (3)>]>

>>> Student.objects.all()[1]				#所有Student对象中索引为1的元素
<Student: Student object (2)>

>>> Student.objects.all()[1].name			#所有Student对象中索引为1的元素的名字是
'alice'

>>> Student.objects.get(id=3)				#通过get函数获取id等于3的对象
<Student: Student object (3)>

>>> Student.objects.get(id=3).name			#根据获取的id=3的对象获取名字
'dd'

 三、一对多 & 多对多&一对一

###############################一对多####################################
在models.py中创建School和Student
	class School(models.Model):
		school_name = models.CharField(max_length=20)
		school_address = models.CharField(max_length=50)

	class Student(models.Model):
		name = models.CharField(max_length=10)
		sex = models.CharField(max_length=10)
		score = models.FloatField()
		#Django2.0 必须添加on_delete=models.CASCADE,级联删除
		school = models.ForeignKey(School,on_delete=models.CASCADE)

"一对多"关系表设计
	在“多”方设置外键(foreign key),关联父表(主表)的主键。
	
	例子:
	#添加学校记录:
	school1 = School(school_name='清华大学',school_address='北京')
	school1.save()
	或者
	School.objects.create(school_name='南开大学',school_address='天津')

	#添加学生记录(要进行关联学校记录)
	#通过学校的实例化对象关联
	stu4 = Student(name="李红",sex='女',score=82,school=school1)
	stu4.save()

	#通过学生的外键列名关联学校的id
	stu4 = Student(name="李红",sex='女',score=82,school_id=24)
	stu4.save()

	#查询学校编号为23或25的学生记录。
	Student.objects.filter(school_id__in =(23,25))

	#查询学号大于9的学生记录
	results = Student.objects.filter(id__gt =9)  # 查询出的是QuerySet对象
	for stu in results:
		print(stu.name)
		

一对多实例:

#在models.py中创建Country和Province
class Country(models.Model):
    name = models.CharField(max_length=10)
    address = models.CharField(max_length=10)
class Province(models.Model):
    name = models.CharField(max_length=20)
    cou = models.ForeignKey(Country,on_delete=models.CASCADE)   #设置外键,关联国家
		
#在交互环境下(Terminal)进行操作
python manage.py makemigrations
python manage.py migrate
python manage.py shell

>>> from homework.models import *
>>> country1 = Country(name='中国',address='亚洲')
>>> country1.save()
>>> pro1 = Province(name='陕西省',cou=country1)
>>> pro1.save()
>>> pro2 = Province(name='河北省',cou_id=1)
>>> pro2.save()

>>> country2 = Country(name='美国',address='北美洲')
>>> country2.save()
>>> pro1 = Province(name='加州',cou=country2)
>>> pro1.save()
>>> pro2 = Province(name='圣州',cou=country2)
>>> pro2.save()
>>> exit()				#创建好后退出交互环境

D:\django\ReviewDjango>python manage.py shell

>>> from homework.models import *
>>> cou1=Country.objects.get(name='China')
>>> cou1
<Country: Country object (1)>

>>> cou1.province_set.all()				#通过国家查省份(通过少查多)
<QuerySet [<Province: Province object (1)>, <Province: Province object (2)>]>

>>> pros = cou1.province_set.all()
>>> for pro in pros:
...     print(pro.name)
...
陕西省
河北省

>>> pro = Province.objects.get(id=4)
>>> pro
<Province: Province object (4)>

>>> pro.cou
<Country: Country object (2)>

>>> pro.cou.name						#通过省份查国家(通过多查少)。多方有cou属性。可以直接使用
'USA'

 

################################多对多########################################
"多对多"关系表设计
	通过设置“中间表”来关联两个“多”表。中间表中至少有两个外键字段,分别关联于两个“多”表的主键。
	在Django的models.py中需要完成三个模型:
		class Author(models.Model):
			name = models.CharField(max_length=20)
			home = models.CharField(max_length=20)

		class Book(models.Model):
			bookname = models.CharField(max_length=20)
			bookprice = models.FloatField()
			author = models.ManyToManyField(Author,through="Author_Book")

		中间关系模型:
		class Author_Book(models.Model):
			author = models.ForeignKey(Author,on_delete=models.CASCADE)
			book = models.ForeignKey(Book,on_delete=models.CASCADE)

	插入“多”方表数据:	
	author1 = Author(name='金庸',home='香港')
	author1.save()  # 或使用Author.objects.create(name='金庸',home='香港')

	book1 = ...

	通过中间模型对象插入中间表数据:
	ab1 = Author_Book(author=author1,book=book1)
	ab1.save()

	从多方查询另一方数据:
	从主动多方(调用了ManyToManyField方法())查询另一个多方:
	book3.author.all()

	从被动多方查询另一个多方:
	author1.book_set.all()   

 多对多实例:

#多对多例题:

第一步:先在app下的models中创建class
from django.db import models
class Author(models.Model):
    name = models.CharField(max_length=20)
    home = models.CharField(max_length=20)

class Book(models.Model):
    bookname = models.CharField(max_length=20)
    bookprice = models.FloatField()
    author = models.ManyToManyField(Author,through='Author_Book')

class Author_Book(models.Model):
    author=models.ForeignKey(Author,on_delete=models.CASCADE)
    book = models.ForeignKey(Book,on_delete=models.CASCADE)

第二步:在Terminal下进行操作

python manage.py makemigrations
...
python manage.py migrate
...

D:\django\DjangoDay4>python manage.py shell
>>> from myapp.models import *
#创建author
>>> author1 = Author(name='金庸',home='香港')
>>> author1.save()
>>> author2 = Author(name='古龙',home='台湾')
>>> author2.save()
#创建book
>>> book1 = Book(bookname='天龙八部',bookprice=52)
>>> book1.save()
>>> book2 = Book(bookname='笑傲江湖',bookprice=26)
>>> book2.save()
#创建关联
>>> ab1 = Author_Book(author=author1,book=book1)
>>> ab1.save()
>>> ab2 = Author_Book(author=author1,book=book2)
>>> ab2.save()
#创建2个作者<--->1本书
>>> book3 = Book(bookname='金龙鱼',bookprice=30)
>>> book3.save()
>>> ab3 = Author_Book(author=author1,book=book3)
>>> ab3.save()
>>> ab4 = Author_Book(author=author2,book=book3)
>>> ab4.save()
#通过书查询其所有作者
>>> book3.author.all()
<QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
#通过作者查询所有书籍
>>> author1.book_set.all()			####这里的book是Book类的小写,并不是Author_Book下的book。
<QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>]>
#对查询的书籍进行遍历
>>> qs = author1.book_set.all()
>>> for b in qs:
...     print(b.bookname)
...
天龙八部
笑傲江湖
金龙鱼
>>>

 一对一实例:

###################################一对一######################################
#在models下创建Person和Card
from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    sex = models.CharField(max_length=10)

class Card(models.Model):
    cardno = models.CharField(max_length=20,unique=True)    #unique 表示此信息为唯一的,不能重复。
    per = models.OneToOneField(Person,on_delete=models.CASCADE)

#在Terminal下进行操作	
python manage.py makemigrations
python manage.py migrate
python manage.py shell

>>> from one2one.models import *
>>> per1 = Person(name='张三',age=20,sex='男')
>>> per1.save()
>>> card1 = Card(cardno='zs123456',per=per1)  #等同于:card1 = Card(cardno='zs123456',per_id=1)
>>> card1.save()

#>>> card2 = Card(cardno='12345678',per=per1)
#>>> card2.save()
#django.db.utils.IntegrityError: (1062, "Duplicate entry '1' for key 'per_id'")
#此处报错是因为在Card类中设置了unique=True。。因此在一对一情况下,per和card只能一对一存在

>>> per1.card.cardno	#通过人查身份证。
'zs123456'
>>> card1.per.name		#通过身份证查人,因为身份证有per属性,可以直接使用。人就只能按照常规方法。
'zhangsan'

 

posted @ 2018-06-22 12:22  Monomania丶pp  阅读(868)  评论(0)    收藏  举报