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>