Django中的连接查询
  • 1、一对一的映射(1:1)
  • ①什么是一对一
  • A表中的一条记录只能与B表中的一条记录匹配关联
  • 数据库中的实现:A表:设计主键;B表:有主键,增加一列,并引用A表中的主键,还得增加一个唯一约束
  • 参考文档(OneToOneField)
  • ②创建一对一映射语法
  • 属性 = models. OneToOneField(Entry)
  • ex:author = models.OneToOneField(Author, null=True, verbose_name=‘丈夫’)
class Wife(models.Model):
    name = models.CharField(max_length=30, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')

    # 增加一对一的关系映射,关联到Author表上
    # 在wife表中自动增加一列,并且是Author表中的主键值,且具有唯一约束
    author = models.OneToOneField(Author, null=True, verbose_name='丈夫')
  • ③查询
  • 正向查询:通过wife查询author
  • wife = Wife.objects.get(id=1)
  • author = wife.author
  • 逆向查询:通过author查询wife
  • author = Author.objects.get(id=1)
  • wife = author.wife
  • 注意:wife属性不在Author的Models类中,但是Django通过OneToOneField在Author中自动默认添加的属性
def oto_views(request):
    wifes = Wife.objects.all()
    authors = Author.objects.all()
    return render(request, 'oto.html', locals())
<!--oto.html-->
<body>
	<!--通过妻子名称查丈夫-->
    {% for wife in wifes %}
        <p>姓名:{{ wife.name }}</p>
        <p>年龄:{{ wife.age }}</p>
        <p>丈夫:{{ wife.author }}</p>
    {% endfor %}
    
    <!--通过丈夫名称查妻子-->
    {% for author in authors %}
        <p>姓名:{{ author.name }}</p>
        <p>年龄:{{ author.age }}</p>
        <p>妻子:{{ author.wife }}</p>
    {% endfor %}
</body>
  • 2、一对多的映射(1:M) 常用
  • ①什么是一对多
  • A表中的一条记录可以与B表中的任意多条记录匹配关联
  • 数据库中的实现:使用外键实现
  • 参考文档(ForeignKey)
  • ②创建一对多映射语法
  • 属性 = models. ForeignKey(Entry)
  • ex:publisher = models.ForeignKey(Publisher, null=True, verbose_name=‘出版社’)
class Book(models.Model):
    title = models.CharField(max_length=50, verbose_name='书名')
    publication_date = models.DateField(default=datetime.now(), verbose_name='出版日期')
    
    # 增加一对多的关系映射,并关联到Publisher表上
    # 在Book表中自动增加一列,并且是Publisher表中的主键值,且没有唯一约束
    publisher = models.ForeignKey(Publisher, null=True, verbose_name='出版社')
  • ③查询
  • 正向查询:通过book查询publisher
  • book = Book.objects.get(id=1)
  • publisher = book.author
  • 逆向查询:通过publisher查询book
  • publisher = Publisher.objects.get(id=1)
  • bookset = publisher.book_set.all()
  • 通过 publisher.book_set.all()得到所有相关联的数据
def otm_views(request):
    books = Book.objects.all()
    publisher = Publisher.objects.all().first()
    bookset = publisher.book_set.all()
    return render(request, 'otm.html', locals())
<!--otm.html-->
<body>
	<!--通过书名查出版社-->
    {% for book in books %}
        <p>书名:{{ book.title }}</p>
        <p>出版时间:{{ book.publication_date }}</p>
        <p>出版社:{{ book.publisher }}</p>
    {% endfor %}

    <!--通过出版社查书籍-->
    <p>出版社:{{ publisher.name }}</p>
    {% for book in bookset %}
        <p>出版书籍:{{ book.title }}</p>
    {% endfor %}
</body>
  • 3、多对多的映射(M:M)
  • ①什么是多对多
  • A表中的一条记录可以与B表中的任意多条记录匹配关联,同时B表中的一条记录可以与A表中的任意多条记录匹配关联
  • 数据库中的实现:新建一个数据表存放多对对映射关系
  • 参考文档(ManyToManyField)
  • ②创建一对一映射语法
  • 属性 = models. ManyToManyField(Entry)
  • ex:author = models.ManyToManyField(Author, null=True)
class Author(models.Model):
    name = models.CharField(max_length=30, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    email = models.EmailField(null=True, verbose_name='邮箱')
    picture = models.ImageField(null=True, upload_to='static/upload/usring', verbose_name='用户头像')
	
	# 增加多对对映射关系
    publisher = models.ManyToManyField(Publisher, null=True, verbose_name='出版社')
  • ③查询
  • 正向查询:通过Author查询Publisher
  • author= Author.objects.get(id=1)
  • publisher_list = author.publisher.all()
  • 逆向查询:通过Publisher查询Author
  • publisher = Publisher.objects.get(id=1)
  • author_list = publisher.author_set.all()
  • 通过 publisher.author_set.all()得到所有相关联的数据
def mtm_views(request):
	# 正向查询
    author = Author.objects.get(id=4)
    publisher_list = author.publisher.all()
	
	# 逆向查询
    publisher = Publisher.objects.get(id=6)
    author_list = publisher.author_set.all()
    return render(request, 'mtm.html', locals())
<!--mtm.html-->
<body>
	<!--通过作者查出版社-->
    <p>作者姓名:{{ author.name }}</p>
	{% for pub in publisher_list %}
    	<p>签约出版社:{{ pub.name }}</p>
	{% endfor %}

    <!--通过出版社查作者-->
    <p>出版社名称:{{ publisher.name }}</p>
	{% for author in author_list %}
    	<p>签约作者:{{ author.name }}</p>
	{% endfor %}
</body>