django之orm多表查询

之前讲了一下单表查询的用法,今天来讲下多表查询的用法。

 

Part1:创建表,生成表

 

# models.py
from django.db import models


# 作者详情表
class AuthorDetail(models.Model):

    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)


# 作者表
class Author(models.Model):

    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    author_detail = models.OneToOneField(to='AuthorDetail', to_field='nid', on_delete=models.CASCADE, null=True)  # 作者表和作者详情表一对一


# 出版社表
class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()


# 书表
class Book(models.Model):

    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32, default='abc')
    publishDate = models.DateField(default=2020-10-20)
    price = models.DecimalField(max_digits=5, decimal_places=2, default=2)

    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE, null=True)  # 书和出版社表多对一

    authors = models.ManyToManyField(to='Author')

models写完以后还是老规矩,执行python manage.py makemigrations  在执行python manage.py migrate ,执行完以后你就会发现数据库中生成了对应的models里面的表了

django之orm多表查询

 

 

 

 

Part2:造数据

首先给publish表新增数据,同样的新增一个视图函数,在视图函数中添加数据

from django.shortcuts import render
from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def show(request):

    Publish.objects.create(name='上海出版社', city='上海', email='18823@163.com')
    Publish.objects.create(name='南京出版社', city='南京', email='12312@163.com')


    return HttpResponse('OK')

执行一下视图函数,查看数据库

django之orm多表查询

 

 

 Publish表数据造好以后,就可以去造和这个表关联的表数据了,通过models显而易见Book(多)和Publish(一)进行了一对多的关联

一对多和一对一添加数据准则:给关联字段赋值,Book表中的关联字段就是publish_id

# model.py

from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def show(request):

    Book.objects.create(title='人与自然', publishDate='2012-10-14', price=200, publish_id=1)
    Book.objects.create(title='三国演义', publishDate='2012-08-14', price=150, publish_id=1)
    Book.objects.create(title='红楼梦', publishDate='2012-10-20', price=350, publish_id=2)

    return HttpResponse('OK')

执行接口后数据就生成了

django之orm多表查询

 

 

 

按同上道理,在author和authordetail也分别添加上数据

django之orm多表查询

 

 

 django之orm多表查询

 

 

 

那么问题来了,现在4个表的数据都加好了,还剩一个book_authors这张表,这张表是Book表和Authors多对多关联生成的,这个时候就要用到django自带的接口了

 

from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def show(request):

    alex = Author.objects.get(name='alex')
    leogao = Author.objects.get(name='leogao')

    # 绑定多对多的接口
    book = Book.objects.get(nid='1')
    book.authors.add(alex, leogao)  # 一张表的对象.另一张表.add(另一张表的对象)




    return HttpResponse('OK')

此时执行视图函数,book_authors就有数据了

 

django之orm多表查询

 

 

 

还有另一种写法

from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def show(request):

    alex = Author.objects.get(nid='1')
    leogao = Author.objects.get(nid='2')

    # 绑定多对多的接口
    book = Book.objects.get(nid='2')
    book.authors.add(1, 2)  # 这边也可以写nid

执行接口查看数据库

django之orm多表查询

 

 

 

比如我们想把刚才绑定的数据分开怎么搞呢,这边django也提供了接口

from django.shortcuts import render
from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def show(request):

    alex = Author.objects.get(nid='1')
    leogao = Author.objects.get(nid='2')

    # 解除多对多
    book = Book.objects.get(nid='2')
    book.authors.remove(1, 2)

执行接口,查看数据库刚才的第二本书就没了(ps:将remove改成clear时就把所有的数据都清除了)

django之orm多表查询

 

 

 新增完数据,接下来就是查询了。

 

Part3:查询

 

1.基于对象查询

 

一对多:

'''
        一对多
        正向查询:按字段
        反向查询:表名小写_set.all()
                                book_obj.publish obj
        Book(关联属性:publish)-------------------->Publish
                             <--------------------
                        publish_obj.book_set.all() # querySet
        '''
from django.http import HttpResponse from showOrmCase.models import * # Create your views here. def analyse(request): # 正向查询:查询三国演义这本书的出版社的名字 name = Book.objects.filter(title='三国演义').first().publish.name print('出版社名字', name) # 反向查询:查询上海出版社出版过的书籍名称 name = Publish.objects.filter(name='上海出版社').first().book_set.all() for i in name: print('书籍名称', i.title) return HttpResponse('OK')

执行视图函数,得到下图结果

django之orm多表查询

 

 

多对多:

'''
            多对多
            正向查询:按字段
            反向查询:表名小写_set.all()
                                    book_obj.authors
            Book(关联属性:author)-------------------->Author
                                 <--------------------
                            author_obj.book_set.all() # querySet
    '''

from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def analyse(request):

    # 正向查询: 查询三国演义这本书的所有作者的名字
    author_name = Book.objects.filter(title='三国演义').first().authors.all().values('name')
    for i in author_name:
        print('作者名字', i['name'])

    # 反向查询: 查询alex出版过的所有书籍名称
    book_name = Author.objects.filter(name='alex').first().book_set.all().values('title')
    for key in book_name:
        print('书籍名称', key['title'])
        
    return HttpResponse('OK')

执行视图函数,得到下图结果

django之orm多表查询

 

 

一对一:

'''
                一对一
                正向查询:按字段
                反向查询:表名小写
                                        author.obj.authordetail
                Author(关联属性:authordetail)-------------------->Authordetail
                                     <--------------------
                                authordetail_obj.author # obj
        '''

from django.http import HttpResponse
from showOrmCase.models import *
# Create your views here.


def analyse(request):

    # 正向查询: 查询alex的手机号
    phone = Author.objects.filter(name='alex').first().author_detail.telephone
    print('手机号', phone)
    # 反向查询:查询手机号为22222的作者的姓名和年龄
    author_name = AuthorDetail.objects.filter(telephone='22222').first().author
    print('名字', author_name.name)
    print('年龄', author_name.age)

    return HttpResponse('OK')

执行视图函数,得到下图结果

django之orm多表查询

 

 

2.基于双下划线跨表查询(join)

 

准则:正向查询按字段,反向查询按表名小写来告诉ORM引擎join哪张表

 

 

一对多:

 

# 正向查询:查询红楼梦这本书的出版社的名字
    publish_name = Book.objects.filter(title='红楼梦').values('publish__name')
    print('正向查询名字:', publish_name)
    # 反向查询
    publish_name_two = Publish.objects.filter(book__title='红楼梦').values('name')
    print('反向查询名字:', publish_name_two)

 

执行视图函数,得到下图结果

django之orm多表查询

 

 

多对多:

name = Book.objects.filter(title='三国演义').values('authors__name')
    print(name)
    # 反向
    name_two = Author.objects.filter(book__title='三国演义').values('name')
    print(name_two)

执行视图函数,得到下图结果

django之orm多表查询

 

 

一对一:

# 对一正向查询: 查询alex的手机号
    phone = Author.objects.filter(name='alex').values('author_detail__telephone')
    print(phone)
    phone_two = AuthorDetail.objects.filter(author__name='alex').values('telephone')
    print(phone_two)

执行视图函数,得到下图结果

django之orm多表查询

 

 

以上就是常用的多表查询方法

 

上一篇:Django数据库增删查改


下一篇:Unity GC 算法->Boehm GC algorithm