关联查询

基础关联查询

# 1.查询编号为1的图书中所有人物信息
# 2.查询编号为1的英雄出自的书籍
  • 1.查询编号为1的图书中所有人物信息

    • 通过书找关联的人

      # 先查编号为1的书
      book = BookInfo.books.get(pk=1)
      # 再通过关联查询到编号为1的书里面的人物信息
      peopleInfos = book.peopleinfo_set.all()
      
  • 2.查询编号为1的人物出自的书籍

    • 通过人找关联的书

      # 先查编号为1的人物
      people = PeopleInfo.objects.get(pk=1)
      # 再通过关联查询编号为1的人物对应的书
      bookInfo = people.book
      

内连接查询

  • 语法如下 :

      filter(关联模型类名小写__属性名__运算符=值)
      例:
      filter(book__name='天龙八部')
    
    • 结果和sql中的inner join相同(内连接)
  • 需求

    # 1.查询书名为"天龙八部"的所有人物信息
    # 2.查询书籍中人物的描述包含"降龙"的书籍
    
  • 1.查询书名为"天龙八部"的所有人物信息(peopleInfo)

    • 通过书找关联的人

      # 原始内连接sql语句:
      select p.name, b.name from peopleinfo as p inner join bookinfo as b on p.book_id = b.id where b.name = "天龙八部";
      
      peopleInfos = PeopleInfo.objects.filter(book__name='天龙八部')
      
  • 2.查询书籍中人物的描述包含"降龙"的书籍

    • 通过人找关联的书

      bookInfos = BookInfo.books.filter(peopleinfo__description__contains='降龙')
      

自关联查询

  • 自关联的表结构:对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以可以设计成一张表,内部的关系字段指向本表的主键
  • 说明:关系属性使用self指向本类,要求null和blank允许为空,因为一级数据是没有父级的

自关联查询演练

  • 1.定义模型类

      # 地区列表信息
      class AreaInfo(models.Model):
          name = models.CharField(max_length=30) #名称
          parent = models.ForeignKey('self',null=True,blank=True) #关系
    
          # 元类信息 :修改表名
          class Meta:
              db_table = 'areainfo'
    
  • 2.迁移

      python manage.py makemigrations
      python manage.py migrate
    
  • 3.导入数据

    • 在桌面准备好areas.sql文件

        mysql -uroot -p
        psd : mysql
        use Bookdb;
        source areas.sql;
      
  • 4.视图部分

      def areaList(request):
          cityInfo = AreaInfo.objects.get(name='广州市')
          context = {'city':cityInfo}
          return render(request, 'Book/arealist.html', context)
    
  • 5.匹配urls

      urlpatterns = [
          # 如果路径是arealist/,就调用视图的areaList函数
          url(r'^arealist/$', views.areaList),
      ]
    
  • 6.模板部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>城市信息</title>
</head>
<body>

    <h1>当前城市:{{ city.name }}</h1>

    <h1>上级省会:{{ city.parent.name }}</h1>

    <h1>下属区县:</h1>
    <ul>
        {% for qu in city.areainfo_set.all %}
            <li>{{ qu.name }}</li>
        {% endfor %}
    </ul>

</body>
</html>