美文网首页
Django模型(四)

Django模型(四)

作者: LinearPi | 来源:发表于2018-08-09 11:04 被阅读0次

Django模型

知识点:

  1. 表关联对象
  2. 多表查询

表关联对象

前向查询

如果一个模型具有ForeignKey,那么该模型的实例将可以通过属性访问关联的(外部)对象。

>>> s1 = Student.objects.get(s_id=1)
>>> s1
<Student: Student<s_id=1,s_name=xiaoming>>
>>> s1.department
<Department: Department<d_id=6,d_name=CC>>
>>> 

你可以通过外键属性获取和设置。和你预期的一样,对外键的修改不会保存到数据库中直至你调用save()。例如:

>>> s1.department
<Department: Department<d_id=6,d_name=CC>>
>>> dx = Department.objects.get(d_id=3)
>>> dx
<Department: Department<d_id=3,d_name=设计>>
>>> s1.department = dx
>>> s1.department 
<Department: Department<d_id=3,d_name=设计>>
>>> s1.save()

反向查询

如果模型I有一个ForeignKey,那么该ForeignKey 所指的模型II实例可以通过一个管理器回前面有ForeignKey的模型I的所有实例。默认情况下,这个管理器的名字为foo_set,其中foo 是源模型的小写名称。

>>> d1 = Department.objects.get(d_id=1)
>>> d1
<Department: Department<d_id=1,d_name=软件>>
>>> d1.student_set.all()
<QuerySet [<Student: Student<s_id=2,s_name=xiaohong>>, <Student: Student<s_id=3,s_name=xiaohua>>, <Student: Student<s_id=4,s_name=xiaoxin>>, <Student: Student<s_id=5,s_name=小明>>]>
>>> 

你可以在ForeignKey 定义时设置related_name 参数来覆盖foo_set 的名称。例如,如果Student模型改成department =models.ForeignKey('Department',related_name='student'),那么上面的示例代码应该改成这样:

>>> from blog.models import Student,Department,Course
>>> d1 = Department.objects.get(d_id=1)
>>> d1.student.all()
<QuerySet [<Student: Student<s_id=2,s_name=xiaohong>>, <Student: Student<s_id=3,s_name=xiaohua>>, <Student: Student<s_id=4,s_name=xiaoxin>>, <Student: Student<s_id=5,s_name=小明>>]>
>>> 

处理关联对象的其它方法

add(obj1, obj2, ...)

添加一指定的模型对象到关联的对象集中。(一对多,多对多)

>>> d1 = Department.objects.get(d_id=4)
>>> d1
<Department: Department<d_id=4,d_name=AA>>
>>> st = Student.objects.get(s_id=6)
>>> st
<Student: Student<s_id=6,s_name=xx>>
>>> d1.student.add(st)

>>> c1 = Course.objects.get(c_id=2)
>>> st.course.add(c1)

create(**kwargs)

创建一个新的对象,将它保存并放在关联的对象集中。返回新创建的对象。(一对多,多对多)

>>> st
<Student: Student<s_id=6,s_name=xx>>
>>> st.course.create(c_name='c++')
<Course: Course<c_id=3,c_name=c++>>
>>> st.course.all()
<QuerySet [<Course: Course<c_id=3,c_name=c++>>]>

remove(obj1, obj2, ...)

从关联的对象集中删除指定的模型对象。(多对多)

>>> s3
<Student: Student<s_id=3,s_name=xiaohua>>
>>> c1
<Course: Course<c_id=2,c_name=java>>
>>> s3.course.all()
<QuerySet [<Course: Course<c_id=1,c_name=python>>, <Course: Course<c_id=2,c_name=java>>, <Course: Course<c_id=3,c_name=c++>>]>
>>> s3.course.remove(c1)

clear()

从关联的对象集中删除所有的对象。(多对多)

>>> s3.course.clear()

注意对于所有类型的关联字段,add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

直接赋值

>>> s2
<Student: Student<s_id=2,s_name=xiaohong>>
>>> cs
<QuerySet [<Course: Course<c_id=3,c_name=c++>>]>
>>> s2.course.all()
<QuerySet []>
>>> s2.course = cs
>>> s2.course.all()
<QuerySet [<Course: Course<c_id=3,c_name=c++>>]>

多表查询

跨关联关系的查询

Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段:

# 查询学院名字为‘软件的’的学生的信息 
Student.objects.filter(department__d_name='软件')

这种跨越可以是任意的深度。

它还可以反向工作。若要引用一个“反向”的关系,只需要使用该模型的小写的名称。

#查询学生名字中包含‘xiao’的学生的学院信息
Department.objects.filter(student__s_name__contains='xiao')

当你基于ManyToManyField或反向的ForeignKey来过滤一个对象时,有两种不同种类的过滤器。考虑Department/Student 关联关系 (一对多的关系)。

# 查询学号为1的学生所有的课程
Course.objects.filter(student__s_id=1)
# 查询报了课程1的所有的学生
Student.objects.filter(course__c_id=1)
# 查询报了'python'课程的的学生的所属学院的信息
Department.objects.filter(student__course__c_name='python')

相关文章

网友评论

      本文标题:Django模型(四)

      本文链接:https://www.haomeiwen.com/subject/oesqbftx.html