1.应用场景:比如文章和标签的关系,一篇文章可以有多个标签,一个标签可以被多个标签引用,因此标签和文章的关系是典型的多对多关系。
2.实现方式:“Django为这种多对多的实现提供了专门的“Field”.叫做“ManyToManyField”。还是拿文章和标签为例进行讲解,出现如下错误:
views.py文件中示例代码如下:
from django.http import HttpResponse
from .models import Article,Tag
def many_to_many(request):
article = Article(title='Hello', content='你好呀')
article.author = User.objects.first()
article.category = Category.objects.first()
tag = Tag(name='新闻')
tag.article_set.add(article)
return HttpResponse("success!")
models.py文件中示例代码如下:
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey('frontuser.User', on_delete=models.CASCADE, default=1)
category = models.ForeignKey('frontuser.Category', on_delete=models.CASCADE, default=1, related_name='articles')
tags = models.ManyToManyField('Tag', related_name='tags')
def __str__(self):
return "<(Article: (id: %s, title: %s, content: %s, author: %s, category: %s))>" % \
(self.id, self.title, self.content, self.author, self.category)
可以通过像一对多表关系中add方法中的可以通过传递参数bulk=False进行保存,但是
tag.article_set.add(article, bulk=False)
之后发现,原来是多对多表关系的对象add方法并没有bulk这个参数。所以只能通过save()方法进行保存。
def many_to_many(request):
article = Article(title='Hello', content='你好呀')
article.author = User.objects.first()
article.category = Category.objects.first()
article.save()
tag = Tag(name='新闻')
tag.save()
article = Article.objects.get(pk=5)
tag.tags.add(article)
return HttpResponse("success!")
同样,可以得到同一位作者的文章,views.py文件是示例代码如下:
from django.http import HttpResponse
from .models import Article,Tag
def many_to_many(request):
articles = Article.objects.filter(author_id=1)
for article in articles:
print(article)
return HttpResponse("success!")
在数据库层面,实现上“Django”是这种多对多的关系建立了一种中间关系映射表,这个映射表分别定义了两个外键,应用到“article”,“tag”两张表的主键。