美文网首页
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